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.Entry;
  29 import com.sun.java.util.jar.pack.ConstantPool.Index;
  30 import com.sun.java.util.jar.pack.Package.Class.Field;
  31 import java.io.BufferedOutputStream;
  32 import java.io.ByteArrayInputStream;
  33 import java.io.ByteArrayOutputStream;
  34 import java.io.EOFException;
  35 import java.io.File;
  36 import java.io.FileOutputStream;
  37 import java.io.FilterInputStream;
  38 import java.io.FilterOutputStream;
  39 import java.io.IOException;
  40 import java.io.InputStream;
  41 import java.io.OutputStream;
  42 import java.io.PrintStream;
  43 import java.util.ArrayList;
  44 import java.util.Arrays;
  45 import java.util.Collections;
  46 import java.util.HashMap;
  47 import java.util.Iterator;
  48 import java.util.List;
  49 import java.util.jar.Pack200;
  50 
  51 /**
  52  * Define the structure and ordering of "bands" in a packed file.
  53  * @author John Rose
  54  */
  55 abstract
  56 class BandStructure implements Constants {
  57     static final int MAX_EFFORT = 9;
  58     static final int MIN_EFFORT = 1;
  59     static final int DEFAULT_EFFORT = 5;
  60 
  61     // Inherit options from Pack200:
  62     PropMap p200 = Utils.currentPropMap();
  63 
  64     int verbose = p200.getInteger(Utils.DEBUG_VERBOSE);
  65     int effort = p200.getInteger(Pack200.Packer.EFFORT);
  66     { if (effort == 0)  effort = DEFAULT_EFFORT; }
  67     boolean optDumpBands = p200.getBoolean(Utils.COM_PREFIX+"dump.bands");
  68     boolean optDebugBands = p200.getBoolean(Utils.COM_PREFIX+"debug.bands");
  69 
  70     // Various heuristic options.
  71     boolean optVaryCodings = !p200.getBoolean(Utils.COM_PREFIX+"no.vary.codings");
  72     boolean optBigStrings = !p200.getBoolean(Utils.COM_PREFIX+"no.big.strings");
  73 
  74     abstract protected Index getCPIndex(byte tag);
  75 
  76     // Local copy of package version.
  77     private int packageMajver = -1;
  78 
  79     /** Call this exactly once, early, to specify the archive major version. */
  80     public void initPackageMajver(int packageMajver) throws IOException {
  81         assert(packageMajver > 0 && packageMajver < 0x10000);
  82         if (this.packageMajver > 0) {
  83             throw new IOException(
  84                 "Package majver is already initialized to " + this.packageMajver+
  85                 "; new setting is " + packageMajver);
  86         }
  87         this.packageMajver = packageMajver;
  88         adjustToMajver();
  89     }
  90     public int getPackageMajver() {
  91         if (packageMajver < 0) {
  92             throw new RuntimeException("Package majver not yet initialized");
  93         }
  94         return packageMajver;
  95     }
  96 
  97     private final boolean isReader = this instanceof PackageReader;
  98     protected BandStructure() {
  99     }
 100 
 101     final static Coding BYTE1 = Coding.of(1,256);
 102 
 103     final static Coding CHAR3 = Coding.of(3,128);
 104     // Note:  Tried sharper (3,16) with no post-zip benefit.
 105 
 106     // This is best used with BCI values:
 107     final static Coding BCI5 = Coding.of(5,4);  // mostly 1-byte offsets
 108     final static Coding BRANCH5 = Coding.of(5,4,2); // mostly forward branches
 109 
 110     final static Coding UNSIGNED5 = Coding.of(5,64);
 111     final static Coding UDELTA5 = UNSIGNED5.getDeltaCoding();
 112     // "sharp" (5,64) zips 0.4% better than "medium" (5,128)
 113     // It zips 1.1% better than "flat" (5,192)
 114 
 115     final static Coding SIGNED5 = Coding.of(5,64,1);  //sharp
 116     final static Coding DELTA5 = SIGNED5.getDeltaCoding();
 117     // Note:  Tried (5,128,2) and (5,192,2) with no benefit.
 118 
 119     final static Coding MDELTA5 = Coding.of(5,64,2).getDeltaCoding();
 120 
 121     final private static Coding[] basicCodings = {
 122         // Table of "Canonical BHSD Codings" from Pack200 spec.
 123         null,  // _meta_default
 124 
 125         // Fixed-length codings:
 126         Coding.of(1,256,0),
 127         Coding.of(1,256,1),
 128         Coding.of(1,256,0).getDeltaCoding(),
 129         Coding.of(1,256,1).getDeltaCoding(),
 130         Coding.of(2,256,0),
 131         Coding.of(2,256,1),
 132         Coding.of(2,256,0).getDeltaCoding(),
 133         Coding.of(2,256,1).getDeltaCoding(),
 134         Coding.of(3,256,0),
 135         Coding.of(3,256,1),
 136         Coding.of(3,256,0).getDeltaCoding(),
 137         Coding.of(3,256,1).getDeltaCoding(),
 138         Coding.of(4,256,0),
 139         Coding.of(4,256,1),
 140         Coding.of(4,256,0).getDeltaCoding(),
 141         Coding.of(4,256,1).getDeltaCoding(),
 142 
 143         // Full-range variable-length codings:
 144         Coding.of(5,  4,0),
 145         Coding.of(5,  4,1),
 146         Coding.of(5,  4,2),
 147         Coding.of(5, 16,0),
 148         Coding.of(5, 16,1),
 149         Coding.of(5, 16,2),
 150         Coding.of(5, 32,0),
 151         Coding.of(5, 32,1),
 152         Coding.of(5, 32,2),
 153         Coding.of(5, 64,0),
 154         Coding.of(5, 64,1),
 155         Coding.of(5, 64,2),
 156         Coding.of(5,128,0),
 157         Coding.of(5,128,1),
 158         Coding.of(5,128,2),
 159 
 160         Coding.of(5,  4,0).getDeltaCoding(),
 161         Coding.of(5,  4,1).getDeltaCoding(),
 162         Coding.of(5,  4,2).getDeltaCoding(),
 163         Coding.of(5, 16,0).getDeltaCoding(),
 164         Coding.of(5, 16,1).getDeltaCoding(),
 165         Coding.of(5, 16,2).getDeltaCoding(),
 166         Coding.of(5, 32,0).getDeltaCoding(),
 167         Coding.of(5, 32,1).getDeltaCoding(),
 168         Coding.of(5, 32,2).getDeltaCoding(),
 169         Coding.of(5, 64,0).getDeltaCoding(),
 170         Coding.of(5, 64,1).getDeltaCoding(),
 171         Coding.of(5, 64,2).getDeltaCoding(),
 172         Coding.of(5,128,0).getDeltaCoding(),
 173         Coding.of(5,128,1).getDeltaCoding(),
 174         Coding.of(5,128,2).getDeltaCoding(),
 175 
 176         // Variable length subrange codings:
 177         Coding.of(2,192,0),
 178         Coding.of(2,224,0),
 179         Coding.of(2,240,0),
 180         Coding.of(2,248,0),
 181         Coding.of(2,252,0),
 182 
 183         Coding.of(2,  8,0).getDeltaCoding(),
 184         Coding.of(2,  8,1).getDeltaCoding(),
 185         Coding.of(2, 16,0).getDeltaCoding(),
 186         Coding.of(2, 16,1).getDeltaCoding(),
 187         Coding.of(2, 32,0).getDeltaCoding(),
 188         Coding.of(2, 32,1).getDeltaCoding(),
 189         Coding.of(2, 64,0).getDeltaCoding(),
 190         Coding.of(2, 64,1).getDeltaCoding(),
 191         Coding.of(2,128,0).getDeltaCoding(),
 192         Coding.of(2,128,1).getDeltaCoding(),
 193         Coding.of(2,192,0).getDeltaCoding(),
 194         Coding.of(2,192,1).getDeltaCoding(),
 195         Coding.of(2,224,0).getDeltaCoding(),
 196         Coding.of(2,224,1).getDeltaCoding(),
 197         Coding.of(2,240,0).getDeltaCoding(),
 198         Coding.of(2,240,1).getDeltaCoding(),
 199         Coding.of(2,248,0).getDeltaCoding(),
 200         Coding.of(2,248,1).getDeltaCoding(),
 201 
 202         Coding.of(3,192,0),
 203         Coding.of(3,224,0),
 204         Coding.of(3,240,0),
 205         Coding.of(3,248,0),
 206         Coding.of(3,252,0),
 207 
 208         Coding.of(3,  8,0).getDeltaCoding(),
 209         Coding.of(3,  8,1).getDeltaCoding(),
 210         Coding.of(3, 16,0).getDeltaCoding(),
 211         Coding.of(3, 16,1).getDeltaCoding(),
 212         Coding.of(3, 32,0).getDeltaCoding(),
 213         Coding.of(3, 32,1).getDeltaCoding(),
 214         Coding.of(3, 64,0).getDeltaCoding(),
 215         Coding.of(3, 64,1).getDeltaCoding(),
 216         Coding.of(3,128,0).getDeltaCoding(),
 217         Coding.of(3,128,1).getDeltaCoding(),
 218         Coding.of(3,192,0).getDeltaCoding(),
 219         Coding.of(3,192,1).getDeltaCoding(),
 220         Coding.of(3,224,0).getDeltaCoding(),
 221         Coding.of(3,224,1).getDeltaCoding(),
 222         Coding.of(3,240,0).getDeltaCoding(),
 223         Coding.of(3,240,1).getDeltaCoding(),
 224         Coding.of(3,248,0).getDeltaCoding(),
 225         Coding.of(3,248,1).getDeltaCoding(),
 226 
 227         Coding.of(4,192,0),
 228         Coding.of(4,224,0),
 229         Coding.of(4,240,0),
 230         Coding.of(4,248,0),
 231         Coding.of(4,252,0),
 232 
 233         Coding.of(4,  8,0).getDeltaCoding(),
 234         Coding.of(4,  8,1).getDeltaCoding(),
 235         Coding.of(4, 16,0).getDeltaCoding(),
 236         Coding.of(4, 16,1).getDeltaCoding(),
 237         Coding.of(4, 32,0).getDeltaCoding(),
 238         Coding.of(4, 32,1).getDeltaCoding(),
 239         Coding.of(4, 64,0).getDeltaCoding(),
 240         Coding.of(4, 64,1).getDeltaCoding(),
 241         Coding.of(4,128,0).getDeltaCoding(),
 242         Coding.of(4,128,1).getDeltaCoding(),
 243         Coding.of(4,192,0).getDeltaCoding(),
 244         Coding.of(4,192,1).getDeltaCoding(),
 245         Coding.of(4,224,0).getDeltaCoding(),
 246         Coding.of(4,224,1).getDeltaCoding(),
 247         Coding.of(4,240,0).getDeltaCoding(),
 248         Coding.of(4,240,1).getDeltaCoding(),
 249         Coding.of(4,248,0).getDeltaCoding(),
 250         Coding.of(4,248,1).getDeltaCoding(),
 251 
 252         null
 253     };
 254     final private static HashMap basicCodingIndexes;
 255     static {
 256         assert(basicCodings[_meta_default] == null);
 257         assert(basicCodings[_meta_canon_min] != null);
 258         assert(basicCodings[_meta_canon_max] != null);
 259         HashMap map = new HashMap();
 260         for (int i = 0; i < basicCodings.length; i++) {
 261             Coding c = basicCodings[i];
 262             if (c == null)  continue;
 263             assert(i >= _meta_canon_min);
 264             assert(i <= _meta_canon_max);
 265             map.put(c, new Integer(i));
 266         }
 267         basicCodingIndexes = map;
 268     }
 269     public static Coding codingForIndex(int i) {
 270         return i < basicCodings.length ? basicCodings[i] : null;
 271     }
 272     public static int indexOf(Coding c) {
 273         Integer i = (Integer) basicCodingIndexes.get(c);
 274         if (i == null)  return 0;
 275         return i.intValue();
 276     }
 277     public static Coding[] getBasicCodings() {
 278         return (Coding[]) basicCodings.clone();
 279     }
 280 
 281     protected byte[] bandHeaderBytes;    // used for input only
 282     protected int    bandHeaderBytePos;  // BHB read pointer, for input only
 283     protected int    bandHeaderBytePos0; // for debug
 284 
 285     protected CodingMethod getBandHeader(int XB, Coding regularCoding) {
 286         CodingMethod[] res = {null};
 287         // push back XB onto the band header bytes
 288         bandHeaderBytes[--bandHeaderBytePos] = (byte) XB;
 289         bandHeaderBytePos0 = bandHeaderBytePos;
 290         // scan forward through XB and any additional band header bytes
 291         bandHeaderBytePos = parseMetaCoding(bandHeaderBytes,
 292                                             bandHeaderBytePos,
 293                                             regularCoding,
 294                                             res);
 295         return res[0];
 296     }
 297 
 298     public static int parseMetaCoding(byte[] bytes, int pos, Coding dflt, CodingMethod[] res) {
 299         if ((bytes[pos] & 0xFF) == _meta_default) {
 300             res[0] = dflt;
 301             return pos+1;
 302         }
 303         int pos2;
 304         pos2 = Coding.parseMetaCoding(bytes, pos, dflt, res);
 305         if (pos2 > pos)  return pos2;
 306         pos2 = PopulationCoding.parseMetaCoding(bytes, pos, dflt, res);
 307         if (pos2 > pos)  return pos2;
 308         pos2 = AdaptiveCoding.parseMetaCoding(bytes, pos, dflt, res);
 309         if (pos2 > pos)  return pos2;
 310         throw new RuntimeException("Bad meta-coding op "+(bytes[pos]&0xFF));
 311     }
 312 
 313     static final int SHORT_BAND_HEURISTIC = 100;
 314 
 315     public static final int NO_PHASE        = 0;
 316 
 317     // package writing phases:
 318     public static final int COLLECT_PHASE   = 1; // collect data before write
 319     public static final int FROZEN_PHASE    = 3; // no longer collecting
 320     public static final int WRITE_PHASE     = 5; // ready to write bytes
 321 
 322     // package reading phases:
 323     public static final int EXPECT_PHASE    = 2; // gather expected counts
 324     public static final int READ_PHASE      = 4; // ready to read bytes
 325     public static final int DISBURSE_PHASE  = 6; // pass out data after read
 326 
 327     public static final int DONE_PHASE      = 8; // done writing or reading
 328 
 329     static boolean phaseIsRead(int p) {
 330         return (p % 2) == 0;
 331     }
 332     static int phaseCmp(int p0, int p1) {
 333         assert((p0 % 2) == (p1 % 2) || (p0 % 8) == 0 || (p1 % 8) == 0);
 334         return p0 - p1;
 335     }
 336 
 337     /** The packed file is divided up into a number of segments.
 338      *  Most segments are typed as ValueBand, strongly-typed sequences
 339      *  of integer values, all interpreted in a single way.
 340      *  A few segments are ByteBands, which hetergeneous sequences
 341      *  of bytes.
 342      *
 343      *  The two phases for writing a packed file are COLLECT and WRITE.
 344      *  1. When writing a packed file, each band collects
 345      *  data in an ad-hoc order.
 346      *  2. At the end, each band is assigned a coding scheme,
 347      *  and then all the bands are written in their global order.
 348      *
 349      *  The three phases for reading a packed file are EXPECT, READ,
 350      *  and DISBURSE.
 351      *  1. For each band, the expected number of integers  is determined.
 352      *  2. The data is actually read from the file into the band.
 353      *  3. The band pays out its values as requested, in an ad hoc order.
 354      *
 355      *  When the last phase of a band is done, it is marked so (DONE).
 356      *  Clearly, these phases must be properly ordered WRT each other.
 357      */
 358     abstract class Band {
 359         private int    phase = NO_PHASE;
 360         private final  String name;
 361 
 362         private int    valuesExpected;
 363 
 364         protected long outputSize = -1;  // cache
 365 
 366         final public Coding regularCoding;
 367 
 368         final public int seqForDebug;
 369         public int       elementCountForDebug;
 370 
 371 
 372         protected Band(String name, Coding regularCoding) {
 373             this.name = name;
 374             this.regularCoding = regularCoding;
 375             this.seqForDebug = ++nextSeqForDebug;
 376             if (verbose > 2)
 377                 Utils.log.fine("Band "+seqForDebug+" is "+name);
 378             // caller must call init
 379         }
 380 
 381         public Band init() {
 382             // Cannot due this from the constructor, because constructor
 383             // may wish to initialize some subclass variables.
 384             // Set initial phase for reading or writing:
 385             if (isReader)
 386                 readyToExpect();
 387             else
 388                 readyToCollect();
 389             return this;
 390         }
 391 
 392         // common operations
 393         boolean isReader() { return isReader; }
 394         int phase() { return phase; }
 395         String name() { return name; }
 396 
 397         /** Return -1 if data buffer not allocated, else max length. */
 398         public abstract int capacity();
 399 
 400         /** Allocate data buffer to specified length. */
 401         protected abstract void setCapacity(int cap);
 402 
 403         /** Return current number of values in buffer, which must exist. */
 404         public abstract int length();
 405 
 406         protected abstract int valuesRemainingForDebug();
 407 
 408         public final int valuesExpected() {
 409             return valuesExpected;
 410         }
 411 
 412         /** Write out bytes, encoding the values. */
 413         public final void writeTo(OutputStream out) throws IOException {
 414             assert(assertReadyToWriteTo(this, out));
 415             setPhase(WRITE_PHASE);
 416             // subclasses continue by writing their contents to output
 417             writeDataTo(out);
 418             doneWriting();
 419         }
 420 
 421         abstract void chooseBandCodings() throws IOException;
 422 
 423         public final long outputSize() {
 424             if (outputSize >= 0) {
 425                 long size = outputSize;
 426                 assert(size == computeOutputSize());
 427                 return size;
 428             }
 429             return computeOutputSize();
 430         }
 431 
 432         protected abstract long computeOutputSize();
 433 
 434         abstract protected void writeDataTo(OutputStream out) throws IOException;
 435 
 436         /** Expect a certain number of values. */
 437         void expectLength(int l) {
 438             assert(assertPhase(this, EXPECT_PHASE));
 439             assert(valuesExpected == 0);  // all at once
 440             assert(l >= 0);
 441             valuesExpected = l;
 442         }
 443         /** Expect more values.  (Multiple calls accumulate.) */
 444         void expectMoreLength(int l) {
 445             assert(assertPhase(this, EXPECT_PHASE));
 446             valuesExpected += l;
 447         }
 448 
 449 
 450         /// Phase change markers.
 451 
 452         private void readyToCollect() { // called implicitly by constructor
 453             setCapacity(1);
 454             setPhase(COLLECT_PHASE);
 455         }
 456         protected void doneWriting() {
 457             assert(assertPhase(this, WRITE_PHASE));
 458             setPhase(DONE_PHASE);
 459         }
 460         private void readyToExpect() { // called implicitly by constructor
 461             setPhase(EXPECT_PHASE);
 462         }
 463         /** Read in bytes, decoding the values. */
 464         public final void readFrom(InputStream in) throws IOException {
 465             assert(assertReadyToReadFrom(this, in));
 466             setCapacity(valuesExpected());
 467             setPhase(READ_PHASE);
 468             // subclasses continue by reading their contents from input:
 469             readDataFrom(in);
 470             readyToDisburse();
 471         }
 472         abstract protected void readDataFrom(InputStream in) throws IOException;
 473         protected void readyToDisburse() {
 474             if (verbose > 1)  Utils.log.fine("readyToDisburse "+this);
 475             setPhase(DISBURSE_PHASE);
 476         }
 477         public void doneDisbursing() {
 478             assert(assertPhase(this, DISBURSE_PHASE));
 479             setPhase(DONE_PHASE);
 480         }
 481         public final void doneWithUnusedBand() {
 482             if (isReader) {
 483                 assert(assertPhase(this, EXPECT_PHASE));
 484                 assert(valuesExpected() == 0);
 485                 // Fast forward:
 486                 setPhase(READ_PHASE);
 487                 setPhase(DISBURSE_PHASE);
 488                 setPhase(DONE_PHASE);
 489             } else {
 490                 setPhase(FROZEN_PHASE);
 491             }
 492         }
 493 
 494         protected void setPhase(int newPhase) {
 495             assert(assertPhaseChangeOK(this, phase, newPhase));
 496             this.phase = newPhase;
 497         }
 498 
 499         protected int lengthForDebug = -1;  // DEBUG ONLY
 500         public String toString() {  // DEBUG ONLY
 501             int length = (lengthForDebug != -1 ? lengthForDebug : length());
 502             String str = name;
 503             if (length != 0)
 504                 str += "[" + length + "]";
 505             if (elementCountForDebug != 0)
 506                 str += "(" + elementCountForDebug + ")";
 507             return str;
 508         }
 509     }
 510 
 511     class ValueBand extends Band {
 512         private int[]  values;   // must be null in EXPECT phase
 513         private int    length;
 514         private int    valuesDisbursed;
 515 
 516         private CodingMethod bandCoding;
 517         private byte[] metaCoding;
 518 
 519         protected ValueBand(String name, Coding regularCoding) {
 520             super(name, regularCoding);
 521         }
 522 
 523         public int capacity() {
 524             return values == null ? -1 : values.length;
 525         }
 526 
 527         /** Declare predicted or needed capacity. */
 528         protected void setCapacity(int cap) {
 529             assert(length <= cap);
 530             if (cap == -1) { values = null; return; }
 531             values = realloc(values, cap);
 532         }
 533 
 534         public int length() {
 535             return length;
 536         }
 537         protected int valuesRemainingForDebug() {
 538             return length - valuesDisbursed;
 539         }
 540         protected int valueAtForDebug(int i) {
 541             return values[i];
 542         }
 543 
 544         void patchValue(int i, int value) {
 545             // Only one use for this.
 546             assert(this == archive_header_S);
 547             assert(i == AH_ARCHIVE_SIZE_HI || i == AH_ARCHIVE_SIZE_LO);
 548             assert(i < length);  // must have already output a dummy
 549             values[i] = value;
 550             outputSize = -1;  // decache
 551         }
 552 
 553         protected void initializeValues(int[] values) {
 554             assert(assertCanChangeLength(this));
 555             assert(length == 0);
 556             this.values = values;
 557             this.length = values.length;
 558         }
 559 
 560         /** Collect one value, or store one decoded value. */
 561         protected void addValue(int x) {
 562             assert(assertCanChangeLength(this));
 563             if (length == values.length)
 564                 setCapacity(length < 1000 ? length * 10 : length * 2);
 565             values[length++] = x;
 566         }
 567 
 568         private boolean canVaryCoding() {
 569             if (!optVaryCodings)           return false;
 570             if (length == 0)               return false;
 571             // Can't read band_headers w/o the archive header:
 572             if (this == archive_header_0)  return false;
 573             if (this == archive_header_S)  return false;
 574             if (this == archive_header_1)  return false;
 575             // BYTE1 bands can't vary codings, but the others can.
 576             // All that's needed for the initial escape is at least
 577             // 256 negative values or more than 256 non-negative values
 578             return (regularCoding.min() <= -256 || regularCoding.max() >= 256);
 579         }
 580 
 581         private boolean shouldVaryCoding() {
 582             assert(canVaryCoding());
 583             if (effort < MAX_EFFORT && length < SHORT_BAND_HEURISTIC)
 584                 return false;
 585             return true;
 586         }
 587 
 588         protected void chooseBandCodings() throws IOException {
 589             boolean canVary = canVaryCoding();
 590             if (!canVary || !shouldVaryCoding()) {
 591                 if (regularCoding.canRepresent(values, 0, length)) {
 592                     bandCoding = regularCoding;
 593                 } else {
 594                     assert(canVary);
 595                     if (verbose > 1)
 596                         Utils.log.fine("regular coding fails in band "+name());
 597                     bandCoding = UNSIGNED5;
 598                 }
 599                 outputSize = -1;
 600             } else {
 601                 int[] sizes = {0,0};
 602                 bandCoding = chooseCoding(values, 0, length,
 603                                           regularCoding, name(),
 604                                           sizes);
 605                 outputSize = sizes[CodingChooser.BYTE_SIZE];
 606                 if (outputSize == 0)  // CodingChooser failed to size it.
 607                     outputSize = -1;
 608             }
 609 
 610             // Compute and save the meta-coding bytes also.
 611             if (bandCoding != regularCoding) {
 612                 metaCoding = bandCoding.getMetaCoding(regularCoding);
 613                 if (verbose > 1) {
 614                     Utils.log.fine("alternate coding "+this+" "+bandCoding);
 615                 }
 616             } else if (canVary &&
 617                        decodeEscapeValue(values[0], regularCoding) >= 0) {
 618                 // Need an explicit default.
 619                 metaCoding = defaultMetaCoding;
 620             } else {
 621                 // Common case:  Zero bytes of meta coding.
 622                 metaCoding = noMetaCoding;
 623             }
 624             if (metaCoding.length > 0
 625                 && (verbose > 2 || verbose > 1 && metaCoding.length > 1)) {
 626                 StringBuffer sb = new StringBuffer();
 627                 for (int i = 0; i < metaCoding.length; i++) {
 628                     if (i == 1)  sb.append(" /");
 629                     sb.append(" ").append(metaCoding[i] & 0xFF);
 630                 }
 631                 Utils.log.fine("   meta-coding "+sb);
 632             }
 633 
 634             assert((outputSize < 0) ||
 635                    !(bandCoding instanceof Coding) ||
 636                    (outputSize == ((Coding)bandCoding)
 637                     .getLength(values, 0, length)))
 638                 : (bandCoding+" : "+
 639                    outputSize+" != "+
 640                    ((Coding)bandCoding).getLength(values, 0, length)
 641                    +" ?= "+getCodingChooser().computeByteSize(bandCoding,values,0,length)
 642                    );
 643 
 644             // Compute outputSize of the escape value X, if any.
 645             if (metaCoding.length > 0) {
 646                 // First byte XB of meta-coding is treated specially,
 647                 // but any other bytes go into the band headers band.
 648                 // This must be done before any other output happens.
 649                 if (outputSize >= 0)
 650                     outputSize += computeEscapeSize();  // good cache
 651                 // Other bytes go into band_headers.
 652                 for (int i = 1; i < metaCoding.length; i++) {
 653                     band_headers.putByte(metaCoding[i] & 0xFF);
 654                 }
 655             }
 656         }
 657 
 658         protected long computeOutputSize() {
 659             outputSize = getCodingChooser().computeByteSize(bandCoding,
 660                                                             values, 0, length);
 661             assert(outputSize < Integer.MAX_VALUE);
 662             outputSize += computeEscapeSize();
 663             return outputSize;
 664         }
 665 
 666         protected int computeEscapeSize() {
 667             if (metaCoding.length == 0)  return 0;
 668             int XB = metaCoding[0] & 0xFF;
 669             int X = encodeEscapeValue(XB, regularCoding);
 670             return regularCoding.setD(0).getLength(X);
 671         }
 672 
 673         protected void writeDataTo(OutputStream out) throws IOException {
 674             if (length == 0)  return;  // nothing to write
 675             long len0 = 0;
 676             if (out == outputCounter) {
 677                 len0 = outputCounter.getCount();
 678             }
 679             if (metaCoding.length > 0) {
 680                 int XB = metaCoding[0] & 0xFF;
 681                 // We need an explicit band header, either because
 682                 // there is a non-default coding method, or because
 683                 // the first value would be parsed as an escape value.
 684                 int X = encodeEscapeValue(XB, regularCoding);
 685                 //System.out.println("X="+X+" XB="+XB+" in "+this);
 686                 regularCoding.setD(0).writeTo(out, X);
 687             }
 688             bandCoding.writeArrayTo(out, values, 0, length);
 689             if (out == outputCounter) {
 690                 long len1 = outputCounter.getCount();
 691                 assert(outputSize == outputCounter.getCount() - len0)
 692                     : (outputSize+" != "+outputCounter.getCount()+"-"+len0);
 693             }
 694             if (optDumpBands)  dumpBand();
 695         }
 696 
 697         protected void readDataFrom(InputStream in) throws IOException {
 698             length = valuesExpected();
 699             if (length == 0)  return;  // nothing to read
 700             if (verbose > 1)
 701                 Utils.log.fine("Reading band "+this);
 702             if (!canVaryCoding()) {
 703                 bandCoding = regularCoding;
 704                 metaCoding = noMetaCoding;
 705             } else {
 706                 assert(in.markSupported());  // input must be buffered
 707                 in.mark(Coding.B_MAX);
 708                 int X = regularCoding.setD(0).readFrom(in);
 709                 int XB = decodeEscapeValue(X, regularCoding);
 710                 if (XB < 0) {
 711                     // Do not consume this value.  No alternate coding.
 712                     in.reset();
 713                     XB = _meta_default;
 714                     bandCoding = regularCoding;
 715                     metaCoding = noMetaCoding;
 716                 } else if (XB == _meta_default) {
 717                     bandCoding = regularCoding;
 718                     metaCoding = defaultMetaCoding;
 719                 } else {
 720                     if (verbose > 2)
 721                         Utils.log.fine("found X="+X+" => XB="+XB);
 722                     bandCoding = getBandHeader(XB, regularCoding);
 723                     // This is really used only by dumpBands.
 724                     int p0 = bandHeaderBytePos0;
 725                     int p1 = bandHeaderBytePos;
 726                     metaCoding = new byte[p1-p0];
 727                     System.arraycopy(bandHeaderBytes, p0,
 728                                      metaCoding, 0, metaCoding.length);
 729                 }
 730             }
 731             if (bandCoding != regularCoding) {
 732                 if (verbose > 1)
 733                     Utils.log.fine(name()+": irregular coding "+bandCoding);
 734             }
 735             bandCoding.readArrayFrom(in, values, 0, length);
 736             if (optDumpBands)  dumpBand();
 737         }
 738 
 739         public void doneDisbursing() {
 740             super.doneDisbursing();
 741             values = null;  // for GC
 742         }
 743 
 744         private void dumpBand() throws IOException {
 745             assert(optDumpBands);
 746             PrintStream ps = new PrintStream(getDumpStream(this, ".txt"));
 747             String irr = (bandCoding == regularCoding) ? "" : " irregular";
 748             ps.print("# length="+length+
 749                      " size="+outputSize()+
 750                      irr+" coding="+bandCoding);
 751             if (metaCoding != noMetaCoding) {
 752                 StringBuffer sb = new StringBuffer();
 753                 for (int i = 0; i < metaCoding.length; i++) {
 754                     if (i == 1)  sb.append(" /");
 755                     sb.append(" ").append(metaCoding[i] & 0xFF);
 756                 }
 757                 ps.print(" //header: "+sb);
 758             }
 759             printArrayTo(ps, values, 0, length);
 760             ps.close();
 761             OutputStream ds = getDumpStream(this, ".bnd");
 762             bandCoding.writeArrayTo(ds, values, 0, length);
 763             ds.close();
 764         }
 765 
 766         /** Disburse one value. */
 767         protected int getValue() {
 768             assert(phase() == DISBURSE_PHASE);
 769             assert(valuesDisbursed < length);
 770             return values[valuesDisbursed++];
 771         }
 772 
 773         /** Reset for another pass over the same value set. */
 774         public void resetForSecondPass() {
 775             assert(phase() == DISBURSE_PHASE);
 776             assert(valuesDisbursed == length());  // 1st pass is complete
 777             valuesDisbursed = 0;
 778         }
 779     }
 780 
 781     class ByteBand extends Band {
 782         private ByteArrayOutputStream bytes;  // input buffer
 783         private ByteArrayOutputStream bytesForDump;
 784         private InputStream in;
 785 
 786         public ByteBand(String name) {
 787             super(name, BYTE1);
 788         }
 789 
 790         public int capacity() {
 791             return bytes == null ? -1 : Integer.MAX_VALUE;
 792         }
 793         protected void setCapacity(int cap) {
 794             assert(bytes == null);  // do this just once
 795             bytes = new ByteArrayOutputStream(cap);
 796         }
 797         public void destroy() {
 798             lengthForDebug = length();
 799             bytes = null;
 800         }
 801 
 802         public int length() {
 803             return bytes == null ? -1 : bytes.size();
 804         }
 805         public void reset() {
 806             bytes.reset();
 807         }
 808         protected int valuesRemainingForDebug() {
 809             return (bytes == null) ? -1 : ((ByteArrayInputStream)in).available();
 810         }
 811 
 812         protected void chooseBandCodings() throws IOException {
 813             // No-op.
 814             assert(decodeEscapeValue(regularCoding.min(), regularCoding) < 0);
 815             assert(decodeEscapeValue(regularCoding.max(), regularCoding) < 0);
 816         }
 817 
 818         protected long computeOutputSize() {
 819             // do not cache
 820             return bytes.size();
 821         }
 822 
 823         public void writeDataTo(OutputStream out) throws IOException {
 824             if (length() == 0)  return;
 825             bytes.writeTo(out);
 826             if (optDumpBands)  dumpBand();
 827             destroy();  // done with the bits!
 828         }
 829 
 830         private void dumpBand() throws IOException {
 831             assert(optDumpBands);
 832             OutputStream ds = getDumpStream(this, ".bnd");
 833             if (bytesForDump != null)
 834                 bytesForDump.writeTo(ds);
 835             else
 836                 bytes.writeTo(ds);
 837             ds.close();
 838         }
 839 
 840         public void readDataFrom(InputStream in) throws IOException {
 841             int vex = valuesExpected();
 842             if (vex == 0)  return;
 843             if (verbose > 1) {
 844                 lengthForDebug = vex;
 845                 Utils.log.fine("Reading band "+this);
 846                 lengthForDebug = -1;
 847             }
 848             byte[] buf = new byte[Math.min(vex, 1<<14)];
 849             while (vex > 0) {
 850                 int nr = in.read(buf, 0, Math.min(vex, buf.length));
 851                 if (nr < 0)  throw new EOFException();
 852                 bytes.write(buf, 0, nr);
 853                 vex -= nr;
 854             }
 855             if (optDumpBands)  dumpBand();
 856         }
 857 
 858         public void readyToDisburse() {
 859             in = new ByteArrayInputStream(bytes.toByteArray());
 860             super.readyToDisburse();
 861         }
 862 
 863         public void doneDisbursing() {
 864             super.doneDisbursing();
 865             if (optDumpBands
 866                 && bytesForDump != null && bytesForDump.size() > 0) {
 867                 try {
 868                     dumpBand();
 869                 } catch (IOException ee) {
 870                     throw new RuntimeException(ee);
 871                 }
 872             }
 873             in = null; // GC
 874             bytes = null;  // GC
 875             bytesForDump = null;  // GC
 876         }
 877 
 878         // alternative to readFrom:
 879         public void setInputStreamFrom(InputStream in) throws IOException {
 880             assert(bytes == null);
 881             assert(assertReadyToReadFrom(this, in));
 882             setPhase(READ_PHASE);
 883             this.in = in;
 884             if (optDumpBands) {
 885                 // Tap the stream.
 886                 bytesForDump = new ByteArrayOutputStream();
 887                 this.in = new FilterInputStream(in) {
 888                     public int read() throws IOException {
 889                         int ch = in.read();
 890                         if (ch >= 0)  bytesForDump.write(ch);
 891                         return ch;
 892                     }
 893                     public int read(byte b[], int off, int len) throws IOException {
 894                         int nr = in.read(b, off, len);
 895                         if (nr >= 0)  bytesForDump.write(b, off, nr);
 896                         return nr;
 897                     }
 898                 };
 899             }
 900             super.readyToDisburse();
 901         }
 902 
 903         public OutputStream collectorStream() {
 904             assert(phase() == COLLECT_PHASE);
 905             assert(bytes != null);
 906             return bytes;
 907         }
 908 
 909         public InputStream getInputStream() {
 910             assert(phase() == DISBURSE_PHASE);
 911             assert(in != null);
 912             return in;
 913         }
 914         public int getByte() throws IOException {
 915             int b = getInputStream().read();
 916             if (b < 0)  throw new EOFException();
 917             return b;
 918         }
 919         public void putByte(int b) throws IOException {
 920             assert(b == (b & 0xFF));
 921             collectorStream().write(b);
 922         }
 923         public String toString() {
 924             return "byte "+super.toString();
 925         }
 926     }
 927 
 928     class IntBand extends ValueBand {
 929         // The usual coding for bands is 7bit/5byte/delta.
 930         public IntBand(String name, Coding regularCoding) {
 931             super(name, regularCoding);
 932         }
 933 
 934         public void putInt(int x) {
 935             assert(phase() == COLLECT_PHASE);
 936             addValue(x);
 937         }
 938 
 939         public int getInt() {
 940             return getValue();
 941         }
 942         /** Return the sum of all values in this band. */
 943         public int getIntTotal() {
 944             assert(phase() == DISBURSE_PHASE);
 945             // assert that this is the whole pass; no other reads allowed
 946             assert(valuesRemainingForDebug() == length());
 947             int total = 0;
 948             for (int k = length(); k > 0; k--) {
 949                 total += getInt();
 950             }
 951             resetForSecondPass();
 952             return total;
 953         }
 954         /** Return the occurrence count of a specific value in this band. */
 955         public int getIntCount(int value) {
 956             assert(phase() == DISBURSE_PHASE);
 957             // assert that this is the whole pass; no other reads allowed
 958             assert(valuesRemainingForDebug() == length());
 959             int total = 0;
 960             for (int k = length(); k > 0; k--) {
 961                 if (getInt() == value) {
 962                     total += 1;
 963                 }
 964             }
 965             resetForSecondPass();
 966             return total;
 967         }
 968     }
 969 
 970     static int getIntTotal(int[] values) {
 971         int total = 0;
 972         for (int i = 0; i < values.length; i++) {
 973             total += values[i];
 974         }
 975         return total;
 976     }
 977 
 978     class CPRefBand extends ValueBand {
 979         Index index;
 980         boolean nullOK;
 981 
 982         public CPRefBand(String name, Coding regularCoding, byte cpTag, boolean nullOK) {
 983             super(name, regularCoding);
 984             this.nullOK = nullOK;
 985             if (cpTag != CONSTANT_None)
 986                 setBandIndex(this, cpTag);
 987         }
 988         public CPRefBand(String name, Coding regularCoding, byte cpTag) {
 989             this(name, regularCoding, cpTag, false);
 990         }
 991         public CPRefBand(String name, Coding regularCoding, Object undef) {
 992             this(name, regularCoding, CONSTANT_None, false);
 993         }
 994 
 995         public void setIndex(Index index) {
 996             this.index = index;
 997         }
 998 
 999         protected void readDataFrom(InputStream in) throws IOException {
1000             super.readDataFrom(in);
1001             assert(assertValidCPRefs(this));
1002         }
1003 
1004         /** Write a constant pool reference. */
1005         public void putRef(Entry e) {
1006             assert(index != null);
1007             addValue(encodeRefOrNull(e, index));
1008         }
1009         public void putRef(Entry e, Index index) {
1010             assert(this.index == null);
1011             addValue(encodeRefOrNull(e, index));
1012         }
1013         public void putRef(Entry e, byte cptag) {
1014             putRef(e, getCPIndex(cptag));
1015         }
1016 
1017         public Entry getRef() {
1018             if (index == null)  Utils.log.warning("No index for "+this);
1019             assert(index != null);
1020             return decodeRefOrNull(getValue(), index);
1021         }
1022         public Entry getRef(Index index) {
1023             assert(this.index == null);
1024             return decodeRefOrNull(getValue(), index);
1025         }
1026         public Entry getRef(byte cptag) {
1027             return getRef(getCPIndex(cptag));
1028         }
1029 
1030         private int encodeRefOrNull(Entry e, Index index) {
1031             int nonNullCode;  // NNC is the coding which assumes nulls are rare
1032             if (e == null) {
1033                 nonNullCode = -1;  // negative values are rare
1034             } else {
1035                 nonNullCode = encodeRef(e, index);
1036             }
1037             // If nulls are expected, increment, to make -1 code turn to 0.
1038             return (nullOK ? 1 : 0) + nonNullCode;
1039         }
1040         private Entry decodeRefOrNull(int code, Index index) {
1041             // Inverse to encodeRefOrNull...
1042             int nonNullCode = code - (nullOK ? 1 : 0);
1043             if (nonNullCode == -1) {
1044                 return null;
1045             } else {
1046                 return decodeRef(nonNullCode, index);
1047             }
1048         }
1049     }
1050 
1051     // Bootstrap support for CPRefBands.  These are needed to record
1052     // intended CP indexes, before the CP has been created.
1053     private ArrayList allKQBands = new ArrayList();
1054     private ArrayList needPredefIndex = new ArrayList();
1055 
1056 
1057     int encodeRef(Entry e, Index ix) {
1058         int coding = ix.indexOf(e);
1059         if (verbose > 2)
1060             Utils.log.fine("putRef "+coding+" => "+e);
1061         return coding;
1062     }
1063 
1064     Entry decodeRef(int n, Index ix) {
1065         if (n < 0 || n >= ix.size())
1066             Utils.log.warning("decoding bad ref "+n+" in "+ix);
1067         Entry e = ix.getEntry(n);
1068         if (verbose > 2)
1069             Utils.log.fine("getRef "+n+" => "+e);
1070         return e;
1071     }
1072 
1073     private CodingChooser codingChooser;
1074     protected CodingChooser getCodingChooser() {
1075         if (codingChooser == null) {
1076             codingChooser = new CodingChooser(effort, basicCodings);
1077             if (codingChooser.stress != null
1078                 && this instanceof PackageWriter) {
1079                 // Twist the random state based on my first file.
1080                 // This sends each segment off in a different direction.
1081                 List classes = ((PackageWriter)this).pkg.classes;
1082                 if (!classes.isEmpty()) {
1083                     Package.Class cls = (Package.Class) classes.get(0);
1084                     codingChooser.addStressSeed(cls.getName().hashCode());
1085                 }
1086             }
1087         }
1088         return codingChooser;
1089     }
1090 
1091     public CodingMethod chooseCoding(int[] values, int start, int end,
1092                                      Coding regular, String bandName,
1093                                      int[] sizes) {
1094         assert(optVaryCodings);
1095         if (effort <= MIN_EFFORT) {
1096             return regular;
1097         }
1098         CodingChooser cc = getCodingChooser();
1099         if (verbose > 1 || cc.verbose > 1) {
1100             Utils.log.fine("--- chooseCoding "+bandName);
1101         }
1102         return cc.choose(values, start, end, regular, sizes);
1103     }
1104 
1105     static final byte[] defaultMetaCoding = { _meta_default };
1106     static final byte[] noMetaCoding      = {};
1107 
1108     // The first value in a band is always coded with the default coding D.
1109     // If this first value X is an escape value, it actually represents the
1110     // first (and perhaps only) byte of a meta-coding.
1111     //
1112     // If D.S != 0 and D includes the range [-256..-1],
1113     // the escape values are in that range,
1114     // and the first byte XB is -1-X.
1115     //
1116     // If D.S == 0 and D includes the range [(D.L)..(D.L)+255],
1117     // the escape values are in that range,
1118     // and XB is X-(D.L).
1119     //
1120     // This representation is designed so that a band header is unlikely
1121     // to be confused with the initial value of a headerless band,
1122     // and yet so that a band header is likely to occupy only a byte or two.
1123     //
1124     // Result is in [0..255] if XB was successfully extracted, else -1.
1125     // See section "Coding Specifier Meta-Encoding" in the JSR 200 spec.
1126     protected static int decodeEscapeValue(int X, Coding regularCoding) {
1127         // The first value in a band is always coded with the default coding D.
1128         // If this first value X is an escape value, it actually represents the
1129         // first (and perhaps only) byte of a meta-coding.
1130         // Result is in [0..255] if XB was successfully extracted, else -1.
1131         if (regularCoding.B() == 1 || regularCoding.L() == 0)
1132             return -1;  // degenerate regular coding (BYTE1)
1133         if (regularCoding.S() != 0) {
1134             if (-256 <= X && X <= -1 && regularCoding.min() <= -256) {
1135                 int XB = -1-X;
1136                 assert(XB >= 0 && XB < 256);
1137                 return XB;
1138             }
1139         } else {
1140             int L = regularCoding.L();
1141             if (L <= X && X <= L+255 && regularCoding.max() >= L+255) {
1142                 int XB = X-L;
1143                 assert(XB >= 0 && XB < 256);
1144                 return XB;
1145             }
1146         }
1147         return -1;  // negative value for failure
1148     }
1149     // Inverse to decodeEscapeValue().
1150     protected static int encodeEscapeValue(int XB, Coding regularCoding) {
1151         assert(XB >= 0 && XB < 256);
1152         assert(regularCoding.B() > 1 && regularCoding.L() > 0);
1153         int X;
1154         if (regularCoding.S() != 0) {
1155             assert(regularCoding.min() <= -256);
1156             X = -1-XB;
1157         } else {
1158             int L = regularCoding.L();
1159             assert(regularCoding.max() >= L+255);
1160             X = XB+L;
1161         }
1162         assert(decodeEscapeValue(X, regularCoding) == XB)
1163             : (regularCoding+" XB="+XB+" X="+X);
1164         return X;
1165     }
1166 
1167     static {
1168         boolean checkXB = false;
1169         assert(checkXB = true);
1170         if (checkXB) {
1171             for (int i = 0; i < basicCodings.length; i++) {
1172                 Coding D = basicCodings[i];
1173                 if (D == null)   continue;
1174                 if (D.B() == 1)  continue;
1175                 if (D.L() == 0)  continue;
1176                 for (int XB = 0; XB <= 255; XB++) {
1177                     // The following exercises decodeEscapeValue also:
1178                     encodeEscapeValue(XB, D);
1179                 }
1180             }
1181         }
1182     }
1183 
1184     class MultiBand extends Band {
1185         MultiBand(String name, Coding regularCoding) {
1186             super(name, regularCoding);
1187         }
1188 
1189         public Band init() {
1190             super.init();
1191             // This is all just to keep the asserts happy:
1192             setCapacity(0);
1193             if (phase() == EXPECT_PHASE) {
1194                 // Fast forward:
1195                 setPhase(READ_PHASE);
1196                 setPhase(DISBURSE_PHASE);
1197             }
1198             return this;
1199         }
1200 
1201         Band[] bands     = new Band[10];
1202         int    bandCount = 0;
1203 
1204         int size() {
1205             return bandCount;
1206         }
1207         Band get(int i) {
1208             assert(i < bandCount);
1209             return bands[i];
1210         }
1211         Band[] toArray() {
1212             return (Band[]) realloc(bands, bandCount);
1213         }
1214 
1215         void add(Band b) {
1216             assert(bandCount == 0 || notePrevForAssert(b, bands[bandCount-1]));
1217             if (bandCount == bands.length) {
1218                 bands = (Band[]) realloc(bands);
1219             }
1220             bands[bandCount++] = b;
1221         }
1222 
1223         ByteBand newByteBand(String name) {
1224             ByteBand b = new ByteBand(name);
1225             b.init(); add(b);
1226             return b;
1227         }
1228         IntBand newIntBand(String name) {
1229             IntBand b = new IntBand(name, regularCoding);
1230             b.init(); add(b);
1231             return b;
1232         }
1233         IntBand newIntBand(String name, Coding regularCoding) {
1234             IntBand b = new IntBand(name, regularCoding);
1235             b.init(); add(b);
1236             return b;
1237         }
1238         MultiBand newMultiBand(String name, Coding regularCoding) {
1239             MultiBand b = new MultiBand(name, regularCoding);
1240             b.init(); add(b);
1241             return b;
1242         }
1243         CPRefBand newCPRefBand(String name, byte cpTag) {
1244             CPRefBand b = new CPRefBand(name, regularCoding, cpTag);
1245             b.init(); add(b);
1246             return b;
1247         }
1248         CPRefBand newCPRefBand(String name, Coding regularCoding,
1249                                byte cpTag) {
1250             CPRefBand b = new CPRefBand(name, regularCoding, cpTag);
1251             b.init(); add(b);
1252             return b;
1253         }
1254         CPRefBand newCPRefBand(String name, Coding regularCoding,
1255                                byte cpTag, boolean nullOK) {
1256             CPRefBand b = new CPRefBand(name, regularCoding, cpTag, nullOK);
1257             b.init(); add(b);
1258             return b;
1259         }
1260 
1261         int bandCount() { return bandCount; }
1262 
1263         private int cap = -1;
1264         public int capacity() { return cap; }
1265         public void setCapacity(int cap) { this.cap = cap; }
1266 
1267         public int length() { return 0; }
1268         public int valuesRemainingForDebug() { return 0; }
1269 
1270         protected void chooseBandCodings() throws IOException {
1271             // coding decision pass
1272             for (int i = 0; i < bandCount; i++) {
1273                 Band b = bands[i];
1274                 b.chooseBandCodings();
1275             }
1276         }
1277 
1278         protected long computeOutputSize() {
1279             // coding decision pass
1280             long sum = 0;
1281             for (int i = 0; i < bandCount; i++) {
1282                 Band b = bands[i];
1283                 long bsize = b.outputSize();
1284                 assert(bsize >= 0) : b;
1285                 sum += bsize;
1286             }
1287             // do not cache
1288             return sum;
1289         }
1290 
1291         protected void writeDataTo(OutputStream out) throws IOException {
1292             long preCount = 0;
1293             if (outputCounter != null)  preCount = outputCounter.getCount();
1294             for (int i = 0; i < bandCount; i++) {
1295                 Band b = bands[i];
1296                 b.writeTo(out);
1297                 if (outputCounter != null) {
1298                     long postCount = outputCounter.getCount();
1299                     long len = postCount - preCount;
1300                     preCount = postCount;
1301                     if ((verbose > 0 && len > 0) || verbose > 1) {
1302                         Utils.log.info("  ...wrote "+len+" bytes from "+b);
1303                     }
1304                 }
1305             }
1306         }
1307 
1308         protected void readDataFrom(InputStream in) throws IOException {
1309             assert(false);  // not called?
1310             for (int i = 0; i < bandCount; i++) {
1311                 Band b = bands[i];
1312                 b.readFrom(in);
1313                 if ((verbose > 0 && b.length() > 0) || verbose > 1) {
1314                     Utils.log.info("  ...read "+b);
1315                 }
1316             }
1317         }
1318 
1319         public String toString() {
1320             return "{"+bandCount()+" bands: "+super.toString()+"}";
1321         }
1322     }
1323 
1324     /**
1325      * An output stream which counts the number of bytes written.
1326      */
1327     private static
1328     class ByteCounter extends FilterOutputStream {
1329         // (should go public under the name CountingOutputStream?)
1330 
1331         private long count;
1332 
1333         public ByteCounter(OutputStream out) {
1334             super(out);
1335         }
1336 
1337         public long getCount() { return count; }
1338         public void setCount(long c) { count = c; }
1339 
1340         public void write(int b) throws IOException {
1341             count++;
1342             if (out != null)  out.write(b);
1343         }
1344         public void write(byte b[], int off, int len) throws IOException {
1345             count += len;
1346             if (out != null)  out.write(b, off, len);
1347         }
1348         public String toString() {
1349             return String.valueOf(getCount());
1350         }
1351     }
1352     ByteCounter outputCounter;
1353 
1354     void writeAllBandsTo(OutputStream out) throws IOException {
1355         // Wrap a byte-counter around the output stream.
1356         outputCounter = new ByteCounter(out);
1357         out = outputCounter;
1358         all_bands.writeTo(out);
1359         if (verbose > 0) {
1360             long nbytes = outputCounter.getCount();
1361             Utils.log.info("Wrote total of "+nbytes+" bytes.");
1362             assert(nbytes == archiveSize0+archiveSize1);
1363         }
1364         outputCounter = null;
1365     }
1366 
1367     // random AO_XXX bits, decoded from the archive header
1368     protected int archiveOptions;
1369 
1370     // archiveSize1 sizes most of the archive [archive_options..file_bits).
1371     protected long archiveSize0; // size through archive_size_lo
1372     protected long archiveSize1; // size reported in archive_header
1373     protected int  archiveNextCount; // reported in archive_header
1374 
1375     static final int AH_LENGTH_0 = 3; //minver, majver, options
1376     static final int AH_ARCHIVE_SIZE_HI = 0;
1377     static final int AH_ARCHIVE_SIZE_LO = 1;
1378     static final int AH_LENGTH_S = 2; //optional size hi/lo
1379     static final int AH_LENGTH = 26;  // mentioned in spec
1380     // Length contributions from optional header fields:
1381     static final int AH_FILE_HEADER_LEN = 5; // sizehi/lo/next/modtime/files
1382     static final int AH_SPECIAL_FORMAT_LEN = 2; // layouts/band-headers
1383     static final int AH_CP_NUMBER_LEN = 4;  // int/float/long/double
1384     static final int AH_LENGTH_MIN = AH_LENGTH
1385         -(AH_SPECIAL_FORMAT_LEN+AH_FILE_HEADER_LEN+AH_CP_NUMBER_LEN);
1386 
1387     // Common structure of attribute band groups:
1388     static final int AB_FLAGS_HI = 0;
1389     static final int AB_FLAGS_LO = 1;
1390     static final int AB_ATTR_COUNT = 2;
1391     static final int AB_ATTR_INDEXES = 3;
1392     static final int AB_ATTR_CALLS = 4;
1393 
1394     static IntBand getAttrBand(MultiBand xxx_attr_bands, int which) {
1395         IntBand b = (IntBand) xxx_attr_bands.get(which);
1396         switch (which) {
1397         case AB_FLAGS_HI:
1398             assert(b.name().endsWith("_flags_hi")); break;
1399         case AB_FLAGS_LO:
1400             assert(b.name().endsWith("_flags_lo")); break;
1401         case AB_ATTR_COUNT:
1402             assert(b.name().endsWith("_attr_count")); break;
1403         case AB_ATTR_INDEXES:
1404             assert(b.name().endsWith("_attr_indexes")); break;
1405         case AB_ATTR_CALLS:
1406             assert(b.name().endsWith("_attr_calls")); break;
1407         default:
1408             assert(false); break;
1409         }
1410         return b;
1411     }
1412 
1413     static private final boolean NULL_IS_OK = true;
1414 
1415     MultiBand all_bands = (MultiBand) new MultiBand("(package)", UNSIGNED5).init();
1416 
1417     // file header (various random bytes)
1418     ByteBand archive_magic = all_bands.newByteBand("archive_magic");
1419     IntBand  archive_header_0 = all_bands.newIntBand("archive_header_0", UNSIGNED5);
1420     IntBand  archive_header_S = all_bands.newIntBand("archive_header_S", UNSIGNED5);
1421     IntBand  archive_header_1 = all_bands.newIntBand("archive_header_1", UNSIGNED5);
1422     ByteBand band_headers = all_bands.newByteBand("band_headers");
1423 
1424     // constant pool contents
1425     MultiBand cp_bands = all_bands.newMultiBand("(constant_pool)", DELTA5);
1426     IntBand   cp_Utf8_prefix = cp_bands.newIntBand("cp_Utf8_prefix");
1427     IntBand   cp_Utf8_suffix = cp_bands.newIntBand("cp_Utf8_suffix", UNSIGNED5);
1428     IntBand   cp_Utf8_chars = cp_bands.newIntBand("cp_Utf8_chars", CHAR3);
1429     IntBand   cp_Utf8_big_suffix = cp_bands.newIntBand("cp_Utf8_big_suffix");
1430     MultiBand cp_Utf8_big_chars = cp_bands.newMultiBand("(cp_Utf8_big_chars)", DELTA5);
1431     IntBand   cp_Int = cp_bands.newIntBand("cp_Int", UDELTA5);
1432     IntBand   cp_Float = cp_bands.newIntBand("cp_Float", UDELTA5);
1433     IntBand   cp_Long_hi = cp_bands.newIntBand("cp_Long_hi", UDELTA5);
1434     IntBand   cp_Long_lo = cp_bands.newIntBand("cp_Long_lo");
1435     IntBand   cp_Double_hi = cp_bands.newIntBand("cp_Double_hi", UDELTA5);
1436     IntBand   cp_Double_lo = cp_bands.newIntBand("cp_Double_lo");
1437     CPRefBand cp_String = cp_bands.newCPRefBand("cp_String", UDELTA5, CONSTANT_Utf8);
1438     CPRefBand cp_Class = cp_bands.newCPRefBand("cp_Class", UDELTA5, CONSTANT_Utf8);
1439     CPRefBand cp_Signature_form = cp_bands.newCPRefBand("cp_Signature_form", CONSTANT_Utf8);
1440     CPRefBand cp_Signature_classes = cp_bands.newCPRefBand("cp_Signature_classes", UDELTA5, CONSTANT_Class);
1441     CPRefBand cp_Descr_name = cp_bands.newCPRefBand("cp_Descr_name", CONSTANT_Utf8);
1442     CPRefBand cp_Descr_type = cp_bands.newCPRefBand("cp_Descr_type", UDELTA5, CONSTANT_Signature);
1443     CPRefBand cp_Field_class = cp_bands.newCPRefBand("cp_Field_class", CONSTANT_Class);
1444     CPRefBand cp_Field_desc = cp_bands.newCPRefBand("cp_Field_desc", UDELTA5, CONSTANT_NameandType);
1445     CPRefBand cp_Method_class = cp_bands.newCPRefBand("cp_Method_class", CONSTANT_Class);
1446     CPRefBand cp_Method_desc = cp_bands.newCPRefBand("cp_Method_desc", UDELTA5, CONSTANT_NameandType);
1447     CPRefBand cp_Imethod_class = cp_bands.newCPRefBand("cp_Imethod_class", CONSTANT_Class);
1448     CPRefBand cp_Imethod_desc = cp_bands.newCPRefBand("cp_Imethod_desc", UDELTA5, CONSTANT_NameandType);
1449 
1450     // bands for carrying attribute definitions:
1451     MultiBand attr_definition_bands = all_bands.newMultiBand("(attr_definition_bands)", UNSIGNED5);
1452     ByteBand attr_definition_headers = attr_definition_bands.newByteBand("attr_definition_headers");
1453     CPRefBand attr_definition_name = attr_definition_bands.newCPRefBand("attr_definition_name", CONSTANT_Utf8);
1454     CPRefBand attr_definition_layout = attr_definition_bands.newCPRefBand("attr_definition_layout", CONSTANT_Utf8);
1455 
1456     // bands for hardwired InnerClasses attribute (shared across the package)
1457     MultiBand ic_bands = all_bands.newMultiBand("(ic_bands)", DELTA5);
1458     CPRefBand ic_this_class = ic_bands.newCPRefBand("ic_this_class", UDELTA5, CONSTANT_Class);
1459     IntBand ic_flags = ic_bands.newIntBand("ic_flags", UNSIGNED5);
1460     // These bands contain data only where flags sets ACC_IC_LONG_FORM:
1461     CPRefBand ic_outer_class = ic_bands.newCPRefBand("ic_outer_class", DELTA5, CONSTANT_Class, NULL_IS_OK);
1462     CPRefBand ic_name = ic_bands.newCPRefBand("ic_name", DELTA5, CONSTANT_Utf8, NULL_IS_OK);
1463 
1464     // bands for carrying class schema information:
1465     MultiBand class_bands = all_bands.newMultiBand("(class_bands)", DELTA5);
1466     CPRefBand class_this = class_bands.newCPRefBand("class_this", CONSTANT_Class);
1467     CPRefBand class_super = class_bands.newCPRefBand("class_super", CONSTANT_Class);
1468     IntBand   class_interface_count = class_bands.newIntBand("class_interface_count");
1469     CPRefBand class_interface = class_bands.newCPRefBand("class_interface", CONSTANT_Class);
1470 
1471     // bands for class members
1472     IntBand   class_field_count = class_bands.newIntBand("class_field_count");
1473     IntBand   class_method_count = class_bands.newIntBand("class_method_count");
1474 
1475     CPRefBand field_descr = class_bands.newCPRefBand("field_descr", CONSTANT_NameandType);
1476     MultiBand field_attr_bands = class_bands.newMultiBand("(field_attr_bands)", UNSIGNED5);
1477     IntBand field_flags_hi = field_attr_bands.newIntBand("field_flags_hi");
1478     IntBand field_flags_lo = field_attr_bands.newIntBand("field_flags_lo");
1479     IntBand field_attr_count = field_attr_bands.newIntBand("field_attr_count");
1480     IntBand field_attr_indexes = field_attr_bands.newIntBand("field_attr_indexes");
1481     IntBand field_attr_calls = field_attr_bands.newIntBand("field_attr_calls");
1482 
1483     // bands for predefined field attributes
1484     CPRefBand field_ConstantValue_KQ = field_attr_bands.newCPRefBand("field_ConstantValue_KQ", CONSTANT_Literal);
1485     CPRefBand field_Signature_RS = field_attr_bands.newCPRefBand("field_Signature_RS", CONSTANT_Signature);
1486     MultiBand field_metadata_bands = field_attr_bands.newMultiBand("(field_metadata_bands)", UNSIGNED5);
1487 
1488     CPRefBand method_descr = class_bands.newCPRefBand("method_descr", MDELTA5, CONSTANT_NameandType);
1489     MultiBand method_attr_bands = class_bands.newMultiBand("(method_attr_bands)", UNSIGNED5);
1490     IntBand  method_flags_hi = method_attr_bands.newIntBand("method_flags_hi");
1491     IntBand  method_flags_lo = method_attr_bands.newIntBand("method_flags_lo");
1492     IntBand  method_attr_count = method_attr_bands.newIntBand("method_attr_count");
1493     IntBand  method_attr_indexes = method_attr_bands.newIntBand("method_attr_indexes");
1494     IntBand  method_attr_calls = method_attr_bands.newIntBand("method_attr_calls");
1495     // band for predefined method attributes
1496     IntBand  method_Exceptions_N = method_attr_bands.newIntBand("method_Exceptions_N");
1497     CPRefBand method_Exceptions_RC = method_attr_bands.newCPRefBand("method_Exceptions_RC", CONSTANT_Class);
1498     CPRefBand method_Signature_RS = method_attr_bands.newCPRefBand("method_Signature_RS", CONSTANT_Signature);
1499     MultiBand method_metadata_bands = method_attr_bands.newMultiBand("(method_metadata_bands)", UNSIGNED5);
1500 
1501     MultiBand class_attr_bands = class_bands.newMultiBand("(class_attr_bands)", UNSIGNED5);
1502     IntBand class_flags_hi = class_attr_bands.newIntBand("class_flags_hi");
1503     IntBand class_flags_lo = class_attr_bands.newIntBand("class_flags_lo");
1504     IntBand class_attr_count = class_attr_bands.newIntBand("class_attr_count");
1505     IntBand class_attr_indexes = class_attr_bands.newIntBand("class_attr_indexes");
1506     IntBand class_attr_calls = class_attr_bands.newIntBand("class_attr_calls");
1507     // band for predefined SourceFile and other class attributes
1508     CPRefBand class_SourceFile_RUN = class_attr_bands.newCPRefBand("class_SourceFile_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
1509     CPRefBand class_EnclosingMethod_RC = class_attr_bands.newCPRefBand("class_EnclosingMethod_RC", CONSTANT_Class);
1510     CPRefBand class_EnclosingMethod_RDN = class_attr_bands.newCPRefBand("class_EnclosingMethod_RDN", UNSIGNED5, CONSTANT_NameandType, NULL_IS_OK);
1511     CPRefBand class_Signature_RS = class_attr_bands.newCPRefBand("class_Signature_RS", CONSTANT_Signature);
1512     MultiBand class_metadata_bands = class_attr_bands.newMultiBand("(class_metadata_bands)", UNSIGNED5);
1513     IntBand   class_InnerClasses_N = class_attr_bands.newIntBand("class_InnerClasses_N");
1514     CPRefBand class_InnerClasses_RC = class_attr_bands.newCPRefBand("class_InnerClasses_RC", CONSTANT_Class);
1515     IntBand   class_InnerClasses_F = class_attr_bands.newIntBand("class_InnerClasses_F");
1516     CPRefBand class_InnerClasses_outer_RCN = class_attr_bands.newCPRefBand("class_InnerClasses_outer_RCN", UNSIGNED5, CONSTANT_Class, NULL_IS_OK);
1517     CPRefBand class_InnerClasses_name_RUN = class_attr_bands.newCPRefBand("class_InnerClasses_name_RUN", UNSIGNED5, CONSTANT_Utf8, NULL_IS_OK);
1518     IntBand class_ClassFile_version_minor_H = class_attr_bands.newIntBand("class_ClassFile_version_minor_H");
1519     IntBand class_ClassFile_version_major_H = class_attr_bands.newIntBand("class_ClassFile_version_major_H");
1520 
1521     MultiBand code_bands = class_bands.newMultiBand("(code_bands)", UNSIGNED5);
1522     ByteBand  code_headers = code_bands.newByteBand("code_headers"); //BYTE1
1523     IntBand   code_max_stack = code_bands.newIntBand("code_max_stack", UNSIGNED5);
1524     IntBand   code_max_na_locals = code_bands.newIntBand("code_max_na_locals", UNSIGNED5);
1525     IntBand   code_handler_count = code_bands.newIntBand("code_handler_count", UNSIGNED5);
1526     IntBand   code_handler_start_P = code_bands.newIntBand("code_handler_start_P", BCI5);
1527     IntBand   code_handler_end_PO = code_bands.newIntBand("code_handler_end_PO", BRANCH5);
1528     IntBand   code_handler_catch_PO = code_bands.newIntBand("code_handler_catch_PO", BRANCH5);
1529     CPRefBand code_handler_class_RCN = code_bands.newCPRefBand("code_handler_class_RCN", UNSIGNED5, CONSTANT_Class, NULL_IS_OK);
1530 
1531     MultiBand code_attr_bands = class_bands.newMultiBand("(code_attr_bands)", UNSIGNED5);
1532     IntBand   code_flags_hi = code_attr_bands.newIntBand("code_flags_hi");
1533     IntBand   code_flags_lo = code_attr_bands.newIntBand("code_flags_lo");
1534     IntBand   code_attr_count = code_attr_bands.newIntBand("code_attr_count");
1535     IntBand   code_attr_indexes = code_attr_bands.newIntBand("code_attr_indexes");
1536     IntBand   code_attr_calls = code_attr_bands.newIntBand("code_attr_calls");
1537 
1538     MultiBand stackmap_bands = code_attr_bands.newMultiBand("StackMapTable_bands", UNSIGNED5);
1539     IntBand   code_StackMapTable_N = stackmap_bands.newIntBand("code_StackMapTable_N");
1540     IntBand   code_StackMapTable_frame_T = stackmap_bands.newIntBand("code_StackMapTable_frame_T",BYTE1);
1541     IntBand   code_StackMapTable_local_N = stackmap_bands.newIntBand("code_StackMapTable_local_N");
1542     IntBand   code_StackMapTable_stack_N = stackmap_bands.newIntBand("code_StackMapTable_stack_N");
1543     IntBand   code_StackMapTable_offset = stackmap_bands.newIntBand("code_StackMapTable_offset", UNSIGNED5);
1544     IntBand   code_StackMapTable_T = stackmap_bands.newIntBand("code_StackMapTable_T", BYTE1);
1545     CPRefBand code_StackMapTable_RC = stackmap_bands.newCPRefBand("code_StackMapTable_RC", CONSTANT_Class);
1546     IntBand   code_StackMapTable_P = stackmap_bands.newIntBand("code_StackMapTable_P", BCI5);
1547 
1548     // bands for predefined LineNumberTable attribute
1549     IntBand   code_LineNumberTable_N = code_attr_bands.newIntBand("code_LineNumberTable_N");
1550     IntBand   code_LineNumberTable_bci_P = code_attr_bands.newIntBand("code_LineNumberTable_bci_P", BCI5);
1551     IntBand   code_LineNumberTable_line = code_attr_bands.newIntBand("code_LineNumberTable_line");
1552 
1553     // bands for predefined LocalVariable{Type}Table attributes
1554     IntBand   code_LocalVariableTable_N = code_attr_bands.newIntBand("code_LocalVariableTable_N");
1555     IntBand   code_LocalVariableTable_bci_P = code_attr_bands.newIntBand("code_LocalVariableTable_bci_P", BCI5);
1556     IntBand   code_LocalVariableTable_span_O = code_attr_bands.newIntBand("code_LocalVariableTable_span_O", BRANCH5);
1557     CPRefBand code_LocalVariableTable_name_RU = code_attr_bands.newCPRefBand("code_LocalVariableTable_name_RU", CONSTANT_Utf8);
1558     CPRefBand code_LocalVariableTable_type_RS = code_attr_bands.newCPRefBand("code_LocalVariableTable_type_RS", CONSTANT_Signature);
1559     IntBand   code_LocalVariableTable_slot = code_attr_bands.newIntBand("code_LocalVariableTable_slot");
1560     IntBand   code_LocalVariableTypeTable_N = code_attr_bands.newIntBand("code_LocalVariableTypeTable_N");
1561     IntBand   code_LocalVariableTypeTable_bci_P = code_attr_bands.newIntBand("code_LocalVariableTypeTable_bci_P", BCI5);
1562     IntBand   code_LocalVariableTypeTable_span_O = code_attr_bands.newIntBand("code_LocalVariableTypeTable_span_O", BRANCH5);
1563     CPRefBand code_LocalVariableTypeTable_name_RU = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_name_RU", CONSTANT_Utf8);
1564     CPRefBand code_LocalVariableTypeTable_type_RS = code_attr_bands.newCPRefBand("code_LocalVariableTypeTable_type_RS", CONSTANT_Signature);
1565     IntBand   code_LocalVariableTypeTable_slot = code_attr_bands.newIntBand("code_LocalVariableTypeTable_slot");
1566 
1567     // bands for bytecodes
1568     MultiBand bc_bands = all_bands.newMultiBand("(byte_codes)", UNSIGNED5);
1569     ByteBand  bc_codes = bc_bands.newByteBand("bc_codes"); //BYTE1
1570     // remaining bands provide typed opcode fields required by the bc_codes
1571 
1572     IntBand   bc_case_count = bc_bands.newIntBand("bc_case_count");  // *switch
1573     IntBand   bc_case_value = bc_bands.newIntBand("bc_case_value", DELTA5);  // *switch
1574     ByteBand  bc_byte = bc_bands.newByteBand("bc_byte"); //BYTE1   // bipush, iinc, *newarray
1575     IntBand   bc_short = bc_bands.newIntBand("bc_short", DELTA5);  // sipush, wide iinc
1576     IntBand   bc_local = bc_bands.newIntBand("bc_local");    // *load, *store, iinc, ret
1577     IntBand   bc_label = bc_bands.newIntBand("bc_label", BRANCH5);    // if*, goto*, jsr*, *switch
1578 
1579     // Most CP refs exhibit some correlation, and benefit from delta coding.
1580     // The notable exceptions are class and method references.
1581 
1582     // ldc* operands:
1583     CPRefBand bc_intref = bc_bands.newCPRefBand("bc_intref", DELTA5, CONSTANT_Integer);
1584     CPRefBand bc_floatref = bc_bands.newCPRefBand("bc_floatref", DELTA5, CONSTANT_Float);
1585     CPRefBand bc_longref = bc_bands.newCPRefBand("bc_longref", DELTA5, CONSTANT_Long);
1586     CPRefBand bc_doubleref = bc_bands.newCPRefBand("bc_doubleref", DELTA5, CONSTANT_Double);
1587     CPRefBand bc_stringref = bc_bands.newCPRefBand("bc_stringref", DELTA5, CONSTANT_String);
1588 
1589     // nulls produced by bc_classref are taken to mean the current class
1590     CPRefBand bc_classref = bc_bands.newCPRefBand("bc_classref", UNSIGNED5, CONSTANT_Class, NULL_IS_OK);   // new, *anew*, c*cast, i*of, ldc
1591     CPRefBand bc_fieldref = bc_bands.newCPRefBand("bc_fieldref", DELTA5, CONSTANT_Fieldref);   // get*, put*
1592     CPRefBand bc_methodref = bc_bands.newCPRefBand("bc_methodref", CONSTANT_Methodref); // invoke[vs]*
1593     CPRefBand bc_imethodref = bc_bands.newCPRefBand("bc_imethodref", DELTA5, CONSTANT_InterfaceMethodref); // invokeinterface
1594 
1595     // _self_linker_op family
1596     CPRefBand bc_thisfield = bc_bands.newCPRefBand("bc_thisfield", CONSTANT_None);     // any field within cur. class
1597     CPRefBand bc_superfield = bc_bands.newCPRefBand("bc_superfield", CONSTANT_None);   // any field within superclass
1598     CPRefBand bc_thismethod = bc_bands.newCPRefBand("bc_thismethod", CONSTANT_None);   // any method within cur. class
1599     CPRefBand bc_supermethod = bc_bands.newCPRefBand("bc_supermethod", CONSTANT_None); // any method within superclass
1600     // bc_invokeinit family:
1601     IntBand   bc_initref = bc_bands.newIntBand("bc_initref");
1602     // escapes
1603     CPRefBand bc_escref = bc_bands.newCPRefBand("bc_escref", CONSTANT_All);
1604     IntBand   bc_escrefsize = bc_bands.newIntBand("bc_escrefsize");
1605     IntBand   bc_escsize = bc_bands.newIntBand("bc_escsize");
1606     ByteBand  bc_escbyte = bc_bands.newByteBand("bc_escbyte");
1607 
1608     // bands for carrying resource files and file attributes:
1609     MultiBand file_bands = all_bands.newMultiBand("(file_bands)", UNSIGNED5);
1610     CPRefBand file_name = file_bands.newCPRefBand("file_name", CONSTANT_Utf8);
1611     IntBand file_size_hi = file_bands.newIntBand("file_size_hi");
1612     IntBand file_size_lo = file_bands.newIntBand("file_size_lo");
1613     IntBand file_modtime = file_bands.newIntBand("file_modtime", DELTA5);
1614     IntBand file_options = file_bands.newIntBand("file_options");
1615     ByteBand file_bits = file_bands.newByteBand("file_bits");
1616 
1617     // End of band definitions!
1618 
1619     /** Given CP indexes, distribute tag-specific indexes to bands. */
1620     protected void setBandIndexes() {
1621         // Handle prior calls to setBandIndex:
1622         for (Iterator i = needPredefIndex.iterator(); i.hasNext(); ) {
1623             Object[] need = (Object[]) i.next();
1624             CPRefBand b     = (CPRefBand) need[0];
1625             Byte      which = (Byte)      need[1];
1626             b.setIndex(getCPIndex(which.byteValue()));
1627         }
1628         needPredefIndex = null;  // no more predefs
1629 
1630         if (verbose > 3) {
1631             printCDecl(all_bands);
1632         }
1633     }
1634 
1635     protected void setBandIndex(CPRefBand b, byte which) {
1636         Object[] need = { b, new Byte(which) };
1637         if (which == CONSTANT_Literal) {
1638             // I.e., attribute layouts KQ (no null) or KQN (null ok).
1639             allKQBands.add(b);
1640         } else if (needPredefIndex != null) {
1641             needPredefIndex.add(need);
1642         } else {
1643             // Not in predefinition mode; getCPIndex now works.
1644             b.setIndex(getCPIndex(which));
1645         }
1646     }
1647 
1648     protected void setConstantValueIndex(com.sun.java.util.jar.pack.Package.Class.Field f) {
1649         Index ix = null;
1650         if (f != null) {
1651             byte tag = f.getLiteralTag();
1652             ix = getCPIndex(tag);
1653             if (verbose > 2)
1654                 Utils.log.fine("setConstantValueIndex "+f+" "+ConstantPool.tagName(tag)+" => "+ix);
1655             assert(ix != null);
1656         }
1657         // Typically, allKQBands is the singleton of field_ConstantValue_KQ.
1658         for (Iterator i = allKQBands.iterator(); i.hasNext(); ) {
1659             CPRefBand xxx_KQ = (CPRefBand) i.next();
1660             xxx_KQ.setIndex(ix);
1661         }
1662     }
1663 
1664     // Table of bands which contain metadata.
1665     protected MultiBand[] metadataBands = new MultiBand[ATTR_CONTEXT_LIMIT];
1666     {
1667         metadataBands[ATTR_CONTEXT_CLASS] = class_metadata_bands;
1668         metadataBands[ATTR_CONTEXT_FIELD] = field_metadata_bands;
1669         metadataBands[ATTR_CONTEXT_METHOD] = method_metadata_bands;
1670     }
1671 
1672     // Attribute layouts.
1673     public static final int ADH_CONTEXT_MASK   = 0x3;  // (ad_hdr & ADH_CONTEXT_MASK)
1674     public static final int ADH_BIT_SHIFT      = 0x2;  // (ad_hdr >> ADH_BIT_SHIFT)
1675     public static final int ADH_BIT_IS_LSB     = 1;
1676     public static final int ATTR_INDEX_OVERFLOW  = -1;
1677 
1678     public int[] attrIndexLimit = new int[ATTR_CONTEXT_LIMIT];
1679     // Each index limit is either 32 or 63, depending on AO_HAVE_XXX_FLAGS_HI.
1680 
1681     // Which flag bits are taken over by attributes?
1682     protected long[] attrFlagMask = new long[ATTR_CONTEXT_LIMIT];
1683     // Which flag bits have been taken over explicitly?
1684     protected long[] attrDefSeen = new long[ATTR_CONTEXT_LIMIT];
1685 
1686     // What pseudo-attribute bits are there to watch for?
1687     protected int[] attrOverflowMask = new int[ATTR_CONTEXT_LIMIT];
1688     protected int attrClassFileVersionMask;
1689 
1690     // Mapping from Attribute.Layout to Band[] (layout element bands).
1691     protected HashMap attrBandTable = new HashMap();
1692 
1693     // Well-known attributes:
1694     protected final Attribute.Layout attrCodeEmpty;
1695     protected final Attribute.Layout attrInnerClassesEmpty;
1696     protected final Attribute.Layout attrClassFileVersion;
1697     protected final Attribute.Layout attrConstantValue;
1698 
1699     // Mapping from Attribute.Layout to Integer (inverse of attrDefs)
1700     HashMap attrIndexTable = new HashMap();
1701 
1702     // Mapping from attribute index (<32 are flag bits) to attributes.
1703     protected ArrayList[] attrDefs = new ArrayList[ATTR_CONTEXT_LIMIT];
1704     {
1705         for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1706             assert(attrIndexLimit[i] == 0);
1707             attrIndexLimit[i] = 32;  // just for the sake of predefs.
1708             attrDefs[i] = new ArrayList(Collections.nCopies(attrIndexLimit[i], null));
1709         }
1710 
1711         // Add predefined attribute definitions:
1712         attrInnerClassesEmpty =
1713         predefineAttribute(CLASS_ATTR_InnerClasses, ATTR_CONTEXT_CLASS, null,
1714                            "InnerClasses", "");
1715         assert(attrInnerClassesEmpty == Package.attrInnerClassesEmpty);
1716         predefineAttribute(CLASS_ATTR_SourceFile, ATTR_CONTEXT_CLASS,
1717                            new Band[] { class_SourceFile_RUN },
1718                            "SourceFile", "RUNH");
1719         predefineAttribute(CLASS_ATTR_EnclosingMethod, ATTR_CONTEXT_CLASS,
1720                            new Band[] {
1721                                class_EnclosingMethod_RC,
1722                                class_EnclosingMethod_RDN
1723                            },
1724                            "EnclosingMethod", "RCHRDNH");
1725         attrClassFileVersion =
1726         predefineAttribute(CLASS_ATTR_ClassFile_version, ATTR_CONTEXT_CLASS,
1727                            new Band[] {
1728                                class_ClassFile_version_minor_H,
1729                                class_ClassFile_version_major_H
1730                            },
1731                            ".ClassFile.version", "HH");
1732         predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_CLASS,
1733                            new Band[] { class_Signature_RS },
1734                            "Signature", "RSH");
1735         predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_CLASS, null,
1736                            "Deprecated", "");
1737         //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_CLASS, null,
1738         //                 "Synthetic", "");
1739         predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CLASS, null,
1740                            ".Overflow", "");
1741         attrConstantValue =
1742         predefineAttribute(FIELD_ATTR_ConstantValue, ATTR_CONTEXT_FIELD,
1743                            new Band[] { field_ConstantValue_KQ },
1744                            "ConstantValue", "KQH");
1745         predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_FIELD,
1746                            new Band[] { field_Signature_RS },
1747                            "Signature", "RSH");
1748         predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_FIELD, null,
1749                            "Deprecated", "");
1750         //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_FIELD, null,
1751         //                 "Synthetic", "");
1752         predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_FIELD, null,
1753                            ".Overflow", "");
1754         attrCodeEmpty =
1755         predefineAttribute(METHOD_ATTR_Code, ATTR_CONTEXT_METHOD, null,
1756                            "Code", "");
1757         predefineAttribute(METHOD_ATTR_Exceptions, ATTR_CONTEXT_METHOD,
1758                            new Band[] {
1759                                method_Exceptions_N,
1760                                method_Exceptions_RC
1761                            },
1762                            "Exceptions", "NH[RCH]");
1763         assert(attrCodeEmpty == Package.attrCodeEmpty);
1764         predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_METHOD,
1765                            new Band[] { method_Signature_RS },
1766                            "Signature", "RSH");
1767         predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_METHOD, null,
1768                            "Deprecated", "");
1769         //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_METHOD, null,
1770         //                 "Synthetic", "");
1771         predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_METHOD, null,
1772                            ".Overflow", "");
1773 
1774         for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
1775             MultiBand xxx_metadata_bands = metadataBands[ctype];
1776             if (xxx_metadata_bands == null)
1777                 continue;  // no code attrs
1778 
1779             // These arguments cause the bands to be built
1780             // automatically for this complicated layout:
1781             predefineAttribute(X_ATTR_RuntimeVisibleAnnotations,
1782                                ATTR_CONTEXT_NAME[ctype]+"_RVA_",
1783                                xxx_metadata_bands,
1784                                Attribute.lookup(null, ctype,
1785                                                 "RuntimeVisibleAnnotations"));
1786             predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations,
1787                                ATTR_CONTEXT_NAME[ctype]+"_RIA_",
1788                                xxx_metadata_bands,
1789                                Attribute.lookup(null, ctype,
1790                                                 "RuntimeInvisibleAnnotations"));
1791             if (ctype != ATTR_CONTEXT_METHOD)
1792                 continue;
1793 
1794             predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
1795                                "method_RVPA_", xxx_metadata_bands,
1796                                Attribute.lookup(null, ctype,
1797                                                 "RuntimeVisibleParameterAnnotations"));
1798             predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
1799                                "method_RIPA_", xxx_metadata_bands,
1800                                Attribute.lookup(null, ctype,
1801                                                 "RuntimeInvisibleParameterAnnotations"));
1802             predefineAttribute(METHOD_ATTR_AnnotationDefault,
1803                                "method_AD_", xxx_metadata_bands,
1804                                Attribute.lookup(null, ctype,
1805                                                 "AnnotationDefault"));
1806         }
1807 
1808 
1809         Attribute.Layout stackMapDef = Attribute.lookup(null, ATTR_CONTEXT_CODE, "StackMapTable").layout();
1810         predefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE,
1811                            stackmap_bands.toArray(),
1812                            stackMapDef.name(), stackMapDef.layout());
1813 
1814         predefineAttribute(CODE_ATTR_LineNumberTable, ATTR_CONTEXT_CODE,
1815                            new Band[] {
1816                                code_LineNumberTable_N,
1817                                code_LineNumberTable_bci_P,
1818                                code_LineNumberTable_line
1819                            },
1820                            "LineNumberTable", "NH[PHH]");
1821         predefineAttribute(CODE_ATTR_LocalVariableTable, ATTR_CONTEXT_CODE,
1822                            new Band[] {
1823                                code_LocalVariableTable_N,
1824                                code_LocalVariableTable_bci_P,
1825                                code_LocalVariableTable_span_O,
1826                                code_LocalVariableTable_name_RU,
1827                                code_LocalVariableTable_type_RS,
1828                                code_LocalVariableTable_slot
1829                            },
1830                            "LocalVariableTable", "NH[PHOHRUHRSHH]");
1831         predefineAttribute(CODE_ATTR_LocalVariableTypeTable, ATTR_CONTEXT_CODE,
1832                            new Band[] {
1833                                code_LocalVariableTypeTable_N,
1834                                code_LocalVariableTypeTable_bci_P,
1835                                code_LocalVariableTypeTable_span_O,
1836                                code_LocalVariableTypeTable_name_RU,
1837                                code_LocalVariableTypeTable_type_RS,
1838                                code_LocalVariableTypeTable_slot
1839                            },
1840                            "LocalVariableTypeTable", "NH[PHOHRUHRSHH]");
1841         predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CODE, null,
1842                            ".Overflow", "");
1843 
1844         // Clear the record of having seen these definitions,
1845         // so they may be redefined without error.
1846         for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1847             attrDefSeen[i] = 0;
1848         }
1849 
1850         // Set up the special masks:
1851         for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1852             attrOverflowMask[i] = (1<<X_ATTR_OVERFLOW);
1853             attrIndexLimit[i] = 0;  // will make a final decision later
1854         }
1855         attrClassFileVersionMask = (1<<CLASS_ATTR_ClassFile_version);
1856     }
1857 
1858     private void adjustToMajver() {
1859         if (getPackageMajver() < JAVA6_PACKAGE_MAJOR_VERSION) {
1860             if (verbose > 0)  Utils.log.fine("Legacy package version");
1861             // Revoke definition of pre-1.6 attribute type.
1862             undefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE);
1863         }
1864     }
1865 
1866     protected void initAttrIndexLimit() {
1867         for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1868             assert(attrIndexLimit[i] == 0);  // decide on it now!
1869             attrIndexLimit[i] = (haveFlagsHi(i)? 63: 32);
1870             assert(attrDefs[i].size() == 32);  // all predef indexes are <32
1871             int addMore = attrIndexLimit[i] - attrDefs[i].size();
1872             attrDefs[i].addAll(Collections.nCopies(addMore, null));
1873         }
1874     }
1875 
1876     protected boolean haveFlagsHi(int ctype) {
1877         int mask = 1<<(LG_AO_HAVE_XXX_FLAGS_HI+ctype);
1878         switch (ctype) {
1879         case ATTR_CONTEXT_CLASS:
1880             assert(mask == AO_HAVE_CLASS_FLAGS_HI); break;
1881         case ATTR_CONTEXT_FIELD:
1882             assert(mask == AO_HAVE_FIELD_FLAGS_HI); break;
1883         case ATTR_CONTEXT_METHOD:
1884             assert(mask == AO_HAVE_METHOD_FLAGS_HI); break;
1885         case ATTR_CONTEXT_CODE:
1886             assert(mask == AO_HAVE_CODE_FLAGS_HI); break;
1887         default:
1888             assert(false);
1889         }
1890         return testBit(archiveOptions, mask);
1891     }
1892 
1893     protected ArrayList getPredefinedAttrs(int ctype) {
1894         assert(attrIndexLimit[ctype] != 0);
1895         ArrayList res = new ArrayList(attrIndexLimit[ctype]);
1896         // Remove nulls and non-predefs.
1897         for (int ai = 0; ai < attrIndexLimit[ctype]; ai++) {
1898             if (testBit(attrDefSeen[ctype], 1L<<ai))  continue;
1899             Attribute.Layout def = (Attribute.Layout) attrDefs[ctype].get(ai);
1900             if (def == null)  continue;  // unused flag bit
1901             assert(isPredefinedAttr(ctype, ai));
1902             res.add(def);
1903         }
1904         return res;
1905     }
1906 
1907     protected boolean isPredefinedAttr(int ctype, int ai) {
1908         assert(attrIndexLimit[ctype] != 0);
1909         // Overflow attrs are never predefined.
1910         if (ai >= attrIndexLimit[ctype])          return false;
1911         // If the bit is set, it was explicitly def'd.
1912         if (testBit(attrDefSeen[ctype], 1L<<ai))  return false;
1913         return (attrDefs[ctype].get(ai) != null);
1914     }
1915 
1916     protected void adjustSpecialAttrMasks() {
1917         // Clear special masks if new definitions have been seen for them.
1918         attrClassFileVersionMask &= ~ attrDefSeen[ATTR_CONTEXT_CLASS];
1919         // It is possible to clear the overflow mask (bit 16).
1920         for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1921             attrOverflowMask[i] &= ~ attrDefSeen[i];
1922         }
1923     }
1924 
1925     protected Attribute makeClassFileVersionAttr(int minver, int majver) {
1926         byte[] bytes = {
1927             (byte)(minver >> 8), (byte)minver,
1928             (byte)(majver >> 8), (byte)majver
1929         };
1930         return attrClassFileVersion.addContent(bytes);
1931     }
1932 
1933     protected short[] parseClassFileVersionAttr(Attribute attr) {
1934         assert(attr.layout() == attrClassFileVersion);
1935         assert(attr.size() == 4);
1936         byte[] bytes = attr.bytes();
1937         int minver = ((bytes[0] & 0xFF) << 8) | (bytes[1] & 0xFF);
1938         int majver = ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF);
1939         return new short[]{ (short) minver, (short) majver };
1940     }
1941 
1942     private boolean assertBandOKForElems(Band[] ab, Attribute.Layout.Element[] elems) {
1943         for (int i = 0; i < elems.length; i++) {
1944             assert(assertBandOKForElem(ab, elems[i]));
1945         }
1946         return true;
1947     }
1948     private boolean assertBandOKForElem(Band[] ab, Attribute.Layout.Element e) {
1949         Band b = null;
1950         if (e.bandIndex != Attribute.NO_BAND_INDEX)
1951             b = ab[e.bandIndex];
1952         Coding rc = UNSIGNED5;
1953         boolean wantIntBand = true;
1954         switch (e.kind) {
1955         case Attribute.EK_INT:
1956             if (e.flagTest(Attribute.EF_SIGN)) {
1957                 rc = SIGNED5;
1958             } else if (e.len == 1) {
1959                 rc = BYTE1;
1960             }
1961             break;
1962         case Attribute.EK_BCI:
1963             if (!e.flagTest(Attribute.EF_DELTA)) {
1964                 rc = BCI5;
1965             } else {
1966                 rc = BRANCH5;
1967             }
1968             break;
1969         case Attribute.EK_BCO:
1970             rc = BRANCH5;
1971             break;
1972         case Attribute.EK_FLAG:
1973             if (e.len == 1)  rc = BYTE1;
1974             break;
1975         case Attribute.EK_REPL:
1976             if (e.len == 1)  rc = BYTE1;
1977             assertBandOKForElems(ab, e.body);
1978             break;
1979         case Attribute.EK_UN:
1980             if (e.flagTest(Attribute.EF_SIGN)) {
1981                 rc = SIGNED5;
1982             } else if (e.len == 1) {
1983                 rc = BYTE1;
1984             }
1985             assertBandOKForElems(ab, e.body);
1986             break;
1987         case Attribute.EK_CASE:
1988             assert(b == null);
1989             assertBandOKForElems(ab, e.body);
1990             return true;  // no direct band
1991         case Attribute.EK_CALL:
1992             assert(b == null);
1993             return true;  // no direct band
1994         case Attribute.EK_CBLE:
1995             assert(b == null);
1996             assertBandOKForElems(ab, e.body);
1997             return true;  // no direct band
1998         case Attribute.EK_REF:
1999             wantIntBand = false;
2000             assert(b instanceof CPRefBand);
2001             assert(((CPRefBand)b).nullOK == e.flagTest(Attribute.EF_NULL));
2002             break;
2003         default: assert(false);
2004         }
2005         assert(b.regularCoding == rc)
2006             : (e+" // "+b);
2007         if (wantIntBand)
2008             assert(b instanceof IntBand);
2009         return true;
2010     }
2011 
2012     private
2013     Attribute.Layout predefineAttribute(int index, int ctype, Band[] ab,
2014                                         String name, String layout) {
2015         // Use Attribute.find to get uniquification of layouts.
2016         Attribute.Layout def = Attribute.find(ctype, name, layout).layout();
2017         //def.predef = true;
2018         if (index >= 0) {
2019             setAttributeLayoutIndex(def, index);
2020         }
2021         if (ab == null) {
2022             ab = new Band[0];
2023         }
2024         assert(attrBandTable.get(def) == null);  // no redef
2025         attrBandTable.put(def, ab);
2026         assert(def.bandCount == ab.length)
2027             : (def+" // "+Arrays.asList(ab));
2028         // Let's make sure the band types match:
2029         assert(assertBandOKForElems(ab, def.elems));
2030         return def;
2031     }
2032 
2033     // This version takes bandPrefix/addHere instead of prebuilt Band[] ab.
2034     private
2035     Attribute.Layout predefineAttribute(int index,
2036                                         String bandPrefix, MultiBand addHere,
2037                                         Attribute attr) {
2038         //Attribute.Layout def = Attribute.find(ctype, name, layout).layout();
2039         Attribute.Layout def = attr.layout();
2040         int ctype = def.ctype();
2041         return predefineAttribute(index, ctype,
2042                                   makeNewAttributeBands(bandPrefix, def,
2043                                                         addHere),
2044                                   def.name(), def.layout());
2045     }
2046 
2047     private
2048     void undefineAttribute(int index, int ctype) {
2049         if (verbose > 1) {
2050             System.out.println("Removing predefined "+ATTR_CONTEXT_NAME[ctype]+
2051                                " attribute on bit "+index);
2052         }
2053         List defList = attrDefs[ctype];
2054         Attribute.Layout def = (Attribute.Layout) defList.get(index);
2055         assert(def != null);
2056         defList.set(index, null);
2057         attrIndexTable.put(def, null);
2058         // Clear the def bit.  (For predefs, it's already clear.)
2059         assert(index < 64);
2060         attrDefSeen[ctype]  &= ~(1L<<index);
2061         attrFlagMask[ctype] &= ~(1L<<index);
2062         Band[] ab = (Band[]) attrBandTable.get(def);
2063         for (int j = 0; j < ab.length; j++) {
2064             ab[j].doneWithUnusedBand();
2065         }
2066     }
2067 
2068     // Bands which contain non-predefined attrs.
2069     protected MultiBand[] attrBands = new MultiBand[ATTR_CONTEXT_LIMIT];
2070     {
2071         attrBands[ATTR_CONTEXT_CLASS] = class_attr_bands;
2072         attrBands[ATTR_CONTEXT_FIELD] = field_attr_bands;
2073         attrBands[ATTR_CONTEXT_METHOD] = method_attr_bands;
2074         attrBands[ATTR_CONTEXT_CODE] = code_attr_bands;
2075     }
2076 
2077     // Create bands for all non-predefined attrs.
2078     void makeNewAttributeBands() {
2079         // Retract special flag bit bindings, if they were taken over.
2080         adjustSpecialAttrMasks();
2081 
2082         for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
2083             String cname = ATTR_CONTEXT_NAME[ctype];
2084             MultiBand xxx_attr_bands = attrBands[ctype];
2085             long defSeen = attrDefSeen[ctype];
2086             // Note: attrDefSeen is always a subset of attrFlagMask.
2087             assert((defSeen & ~attrFlagMask[ctype]) == 0);
2088             for (int i = 0; i < attrDefs[ctype].size(); i++) {
2089                 Attribute.Layout def = (Attribute.Layout)
2090                     attrDefs[ctype].get(i);
2091                 if (def == null)  continue;  // unused flag bit
2092                 if (def.bandCount == 0)  continue;  // empty attr
2093                 if (i < attrIndexLimit[ctype] && !testBit(defSeen, 1L<<i)) {
2094                     // There are already predefined bands here.
2095                     assert(attrBandTable.get(def) != null);
2096                     continue;
2097                 }
2098                 int base = xxx_attr_bands.size();
2099                 String pfx = cname+"_"+def.name()+"_";  // debug only
2100                 if (verbose > 1)
2101                     Utils.log.fine("Making new bands for "+def);
2102                 Band[] newAB  = makeNewAttributeBands(pfx, def,
2103                                                       xxx_attr_bands);
2104                 assert(newAB.length == def.bandCount);
2105                 Band[] prevAB = (Band[]) attrBandTable.put(def, newAB);
2106                 if (prevAB != null) {
2107                     // We won't be using these predefined bands.
2108                     for (int j = 0; j < prevAB.length; j++) {
2109                         prevAB[j].doneWithUnusedBand();
2110                     }
2111                 }
2112             }
2113         }
2114         //System.out.println(prevForAssertMap);
2115     }
2116     private
2117     Band[] makeNewAttributeBands(String pfx, Attribute.Layout def,
2118                                  MultiBand addHere) {
2119         int base = addHere.size();
2120         makeNewAttributeBands(pfx, def.elems, addHere);
2121         int nb = addHere.size() - base;
2122         Band[] newAB = new Band[nb];
2123         for (int i = 0; i < nb; i++) {
2124             newAB[i] = addHere.get(base+i);
2125         }
2126         return newAB;
2127     }
2128     // Recursive helper, operates on a "body" or other sequence of elems:
2129     private
2130     void makeNewAttributeBands(String pfx, Attribute.Layout.Element[] elems,
2131                                MultiBand ab) {
2132         for (int i = 0; i < elems.length; i++) {
2133             Attribute.Layout.Element e = elems[i];
2134             String name = pfx+ab.size()+"_"+e.layout;
2135             {
2136                 int tem;
2137                 if ((tem = name.indexOf('[')) > 0)
2138                     name = name.substring(0, tem);
2139                 if ((tem = name.indexOf('(')) > 0)
2140                     name = name.substring(0, tem);
2141                 if (name.endsWith("H"))
2142                     name = name.substring(0, name.length()-1);
2143             }
2144             Band nb;
2145             switch (e.kind) {
2146             case Attribute.EK_INT:
2147                 nb = newElemBand(e, name, ab);
2148                 break;
2149             case Attribute.EK_BCI:
2150                 if (!e.flagTest(Attribute.EF_DELTA)) {
2151                     // PH:  transmit R(bci), store bci
2152                     nb = ab.newIntBand(name, BCI5);
2153                 } else {
2154                     // POH:  transmit D(R(bci)), store bci
2155                     nb = ab.newIntBand(name, BRANCH5);
2156                 }
2157                 // Note:  No case for BYTE1 here.
2158                 break;
2159             case Attribute.EK_BCO:
2160                 // OH:  transmit D(R(bci)), store D(bci)
2161                 nb = ab.newIntBand(name, BRANCH5);
2162                 // Note:  No case for BYTE1 here.
2163                 break;
2164             case Attribute.EK_FLAG:
2165                 assert(!e.flagTest(Attribute.EF_SIGN));
2166                 nb = newElemBand(e, name, ab);
2167                 break;
2168             case Attribute.EK_REPL:
2169                 assert(!e.flagTest(Attribute.EF_SIGN));
2170                 nb = newElemBand(e, name, ab);
2171                 makeNewAttributeBands(pfx, e.body, ab);
2172                 break;
2173             case Attribute.EK_UN:
2174                 nb = newElemBand(e, name, ab);
2175                 makeNewAttributeBands(pfx, e.body, ab);
2176                 break;
2177             case Attribute.EK_CASE:
2178                 if (!e.flagTest(Attribute.EF_BACK)) {
2179                     // If it's not a duplicate body, make the bands.
2180                     makeNewAttributeBands(pfx, e.body, ab);
2181                 }
2182                 continue;  // no new band to make
2183             case Attribute.EK_REF:
2184                 byte    refKind = e.refKind;
2185                 boolean nullOK  = e.flagTest(Attribute.EF_NULL);
2186                 nb = ab.newCPRefBand(name, UNSIGNED5, refKind, nullOK);
2187                 // Note:  No case for BYTE1 here.
2188                 break;
2189             case Attribute.EK_CALL:
2190                 continue;  // no new band to make
2191             case Attribute.EK_CBLE:
2192                 makeNewAttributeBands(pfx, e.body, ab);
2193                 continue;  // no new band to make
2194             default: assert(false); continue;
2195             }
2196             if (verbose > 1) {
2197                 Utils.log.fine("New attribute band "+nb);
2198             }
2199         }
2200     }
2201     private
2202     Band newElemBand(Attribute.Layout.Element e, String name, MultiBand ab) {
2203         if (e.flagTest(Attribute.EF_SIGN)) {
2204             return ab.newIntBand(name, SIGNED5);
2205         } else if (e.len == 1) {
2206             return ab.newIntBand(name, BYTE1);  // Not ByteBand, please.
2207         } else {
2208             return ab.newIntBand(name, UNSIGNED5);
2209         }
2210     }
2211 
2212     protected int setAttributeLayoutIndex(Attribute.Layout def, int index) {
2213         int ctype = def.ctype;
2214         assert(ATTR_INDEX_OVERFLOW <= index && index < attrIndexLimit[ctype]);
2215         List defList = attrDefs[ctype];
2216         if (index == ATTR_INDEX_OVERFLOW) {
2217             // Overflow attribute.
2218             index = defList.size();
2219             defList.add(def);
2220             if (verbose > 0)
2221                 Utils.log.info("Adding new attribute at "+def +": "+index);
2222             attrIndexTable.put(def, new Integer(index));
2223             return index;
2224         }
2225 
2226         // Detect redefinitions:
2227         if (testBit(attrDefSeen[ctype], 1L<<index)) {
2228             throw new RuntimeException("Multiple explicit definition at "+index+": "+def);
2229         }
2230         attrDefSeen[ctype] |= (1L<<index);
2231 
2232         // Adding a new fixed attribute.
2233         assert(0 <= index && index < attrIndexLimit[ctype]);
2234         if (verbose > (attrClassFileVersionMask == 0? 2:0))
2235             Utils.log.fine("Fixing new attribute at "+index
2236                                +": "+def
2237                                +(defList.get(index) == null? "":
2238                                  "; replacing "+defList.get(index)));
2239         attrFlagMask[ctype] |= (1L<<index);
2240         // Remove index binding of any previous fixed attr.
2241         attrIndexTable.put(defList.get(index), null);
2242         defList.set(index, def);
2243         attrIndexTable.put(def, new Integer(index));
2244         return index;
2245     }
2246 
2247     // encodings found in the code_headers band
2248     private static final int[][] shortCodeLimits = {
2249         { 12, 12 }, // s<12, l<12, e=0 [1..144]
2250         {  8,  8 }, //  s<8,  l<8, e=1 [145..208]
2251         {  7,  7 }, //  s<7,  l<7, e=2 [209..256]
2252     };
2253     public final int shortCodeHeader_h_limit = shortCodeLimits.length;
2254 
2255     // return 0 if it won't encode, else a number in [1..255]
2256     static int shortCodeHeader(Code code) {
2257         int s = code.max_stack;
2258         int l0 = code.max_locals;
2259         int h = code.handler_class.length;
2260         if (h >= shortCodeLimits.length)  return LONG_CODE_HEADER;
2261         int siglen = code.getMethod().getArgumentSize();
2262         assert(l0 >= siglen);  // enough locals for signature!
2263         if (l0 < siglen)  return LONG_CODE_HEADER;
2264         int l1 = l0 - siglen;  // do not count locals required by the signature
2265         int lims = shortCodeLimits[h][0];
2266         int liml = shortCodeLimits[h][1];
2267         if (s >= lims || l1 >= liml)  return LONG_CODE_HEADER;
2268         int sc = shortCodeHeader_h_base(h);
2269         sc += s + lims*l1;
2270         if (sc > 255)  return LONG_CODE_HEADER;
2271         assert(shortCodeHeader_max_stack(sc) == s);
2272         assert(shortCodeHeader_max_na_locals(sc) == l1);
2273         assert(shortCodeHeader_handler_count(sc) == h);
2274         return sc;
2275     }
2276 
2277     static final int LONG_CODE_HEADER = 0;
2278     static int shortCodeHeader_handler_count(int sc) {
2279         assert(sc > 0 && sc <= 255);
2280         for (int h = 0; ; h++) {
2281             if (sc < shortCodeHeader_h_base(h+1))
2282                 return h;
2283         }
2284     }
2285     static int shortCodeHeader_max_stack(int sc) {
2286         int h = shortCodeHeader_handler_count(sc);
2287         int lims = shortCodeLimits[h][0];
2288         return (sc - shortCodeHeader_h_base(h)) % lims;
2289     }
2290     static int shortCodeHeader_max_na_locals(int sc) {
2291         int h = shortCodeHeader_handler_count(sc);
2292         int lims = shortCodeLimits[h][0];
2293         return (sc - shortCodeHeader_h_base(h)) / lims;
2294     }
2295 
2296     private static int shortCodeHeader_h_base(int h) {
2297         assert(h <= shortCodeLimits.length);
2298         int sc = 1;
2299         for (int h0 = 0; h0 < h; h0++) {
2300             int lims = shortCodeLimits[h0][0];
2301             int liml = shortCodeLimits[h0][1];
2302             sc += lims * liml;
2303         }
2304         return sc;
2305     }
2306 
2307     // utilities for accessing the bc_label band:
2308     protected void putLabel(IntBand bc_label, Code c, int pc, int targetPC) {
2309         bc_label.putInt(c.encodeBCI(targetPC) - c.encodeBCI(pc));
2310     }
2311     protected int getLabel(IntBand bc_label, Code c, int pc) {
2312         return c.decodeBCI(bc_label.getInt() + c.encodeBCI(pc));
2313     }
2314 
2315     protected CPRefBand getCPRefOpBand(int bc) {
2316         switch (Instruction.getCPRefOpTag(bc)) {
2317         case CONSTANT_Class:
2318             return bc_classref;
2319         case CONSTANT_Fieldref:
2320             return bc_fieldref;
2321         case CONSTANT_Methodref:
2322             return bc_methodref;
2323         case CONSTANT_InterfaceMethodref:
2324             return bc_imethodref;
2325         case CONSTANT_Literal:
2326             switch (bc) {
2327             case _ildc: case _ildc_w:
2328                 return bc_intref;
2329             case _fldc: case _fldc_w:
2330                 return bc_floatref;
2331             case _lldc2_w:
2332                 return bc_longref;
2333             case _dldc2_w:
2334                 return bc_doubleref;
2335             case _aldc: case _aldc_w:
2336                 return bc_stringref;
2337             case _cldc: case _cldc_w:
2338                 return bc_classref;
2339             }
2340             break;
2341         }
2342         assert(false);
2343         return null;
2344     }
2345 
2346     protected CPRefBand selfOpRefBand(int self_bc) {
2347         assert(Instruction.isSelfLinkerOp(self_bc));
2348         int idx = (self_bc - _self_linker_op);
2349         boolean isSuper = (idx >= _self_linker_super_flag);
2350         if (isSuper)  idx -= _self_linker_super_flag;
2351         boolean isAload = (idx >= _self_linker_aload_flag);
2352         if (isAload)  idx -= _self_linker_aload_flag;
2353         int origBC = _first_linker_op + idx;
2354         boolean isField = Instruction.isFieldOp(origBC);
2355         if (!isSuper)
2356             return isField? bc_thisfield: bc_thismethod;
2357         else
2358             return isField? bc_superfield: bc_supermethod;
2359     }
2360 
2361     ////////////////////////////////////////////////////////////////////
2362 
2363     static int nextSeqForDebug;
2364     static File dumpDir;
2365     static OutputStream getDumpStream(Band b, String ext) throws IOException {
2366         return getDumpStream(b.name, b.seqForDebug, ext, b);
2367     }
2368     static OutputStream getDumpStream(Index ix, String ext) throws IOException {
2369         if (ix.size() == 0)  return new ByteArrayOutputStream();
2370         int seq = ConstantPool.TAG_ORDER[ix.cpMap[0].tag];
2371         return getDumpStream(ix.debugName, seq, ext, ix);
2372     }
2373     static OutputStream getDumpStream(String name, int seq, String ext, Object b) throws IOException {
2374         if (dumpDir == null) {
2375             dumpDir = File.createTempFile("BD_", "", new File("."));
2376             dumpDir.delete();
2377             if (dumpDir.mkdir())
2378                 Utils.log.info("Dumping bands to "+dumpDir);
2379         }
2380         name = name.replace('(', ' ').replace(')', ' ');
2381         name = name.replace('/', ' ');
2382         name = name.replace('*', ' ');
2383         name = name.trim().replace(' ','_');
2384         name = ((10000+seq) + "_" + name).substring(1);
2385         File dumpFile = new File(dumpDir, name+ext);
2386         Utils.log.info("Dumping "+b+" to "+dumpFile);
2387         return new BufferedOutputStream(new FileOutputStream(dumpFile));
2388     }
2389 
2390     // DEBUG ONLY:  Validate me at each length change.
2391     static boolean assertCanChangeLength(Band b) {
2392         switch (b.phase) {
2393         case COLLECT_PHASE:
2394         case READ_PHASE:
2395             return true;
2396         }
2397         return false;
2398     }
2399 
2400     // DEBUG ONLY:  Validate a phase.
2401     static boolean assertPhase(Band b, int phaseExpected) {
2402         if (b.phase() != phaseExpected) {
2403             Utils.log.warning("phase expected "+phaseExpected+" was "+b.phase()+" in "+b);
2404             return false;
2405         }
2406         return true;
2407     }
2408 
2409 
2410     // DEBUG ONLY:  Tells whether verbosity is turned on.
2411     static int verbose() {
2412         return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE);
2413     }
2414 
2415 
2416     // DEBUG ONLY:  Validate me at each phase change.
2417     static boolean assertPhaseChangeOK(Band b, int p0, int p1) {
2418         switch (p0*10+p1) {
2419         /// Writing phases:
2420         case NO_PHASE*10+COLLECT_PHASE:
2421             // Ready to collect data from the input classes.
2422             assert(!b.isReader());
2423             assert(b.capacity() >= 0);
2424             assert(b.length() == 0);
2425             return true;
2426         case COLLECT_PHASE*10+FROZEN_PHASE:
2427         case FROZEN_PHASE*10+FROZEN_PHASE:
2428             assert(b.length() == 0);
2429             return true;
2430         case COLLECT_PHASE*10+WRITE_PHASE:
2431         case FROZEN_PHASE*10+WRITE_PHASE:
2432             // Data is all collected.  Ready to write bytes to disk.
2433             return true;
2434         case WRITE_PHASE*10+DONE_PHASE:
2435             // Done writing to disk.  Ready to reset, in principle.
2436             return true;
2437 
2438         /// Reading phases:
2439         case NO_PHASE*10+EXPECT_PHASE:
2440             assert(b.isReader());
2441             assert(b.capacity() < 0);
2442             return true;
2443         case EXPECT_PHASE*10+READ_PHASE:
2444             // Ready to read values from disk.
2445             assert(Math.max(0,b.capacity()) >= b.valuesExpected());
2446             assert(b.length() <= 0);
2447             return true;
2448         case READ_PHASE*10+DISBURSE_PHASE:
2449             // Ready to disburse values.
2450             assert(b.valuesRemainingForDebug() == b.length());
2451             return true;
2452         case DISBURSE_PHASE*10+DONE_PHASE:
2453             // Done disbursing values.  Ready to reset, in principle.
2454             assert(assertDoneDisbursing(b));
2455             return true;
2456         }
2457         if (p0 == p1)
2458             Utils.log.warning("Already in phase "+p0);
2459         else
2460             Utils.log.warning("Unexpected phase "+p0+" -> "+p1);
2461         return false;
2462     }
2463 
2464     static private boolean assertDoneDisbursing(Band b) {
2465         if (b.phase != DISBURSE_PHASE) {
2466             Utils.log.warning("assertDoneDisbursing: still in phase "+b.phase+": "+b);
2467             if (verbose() <= 1)  return false;  // fail now
2468         }
2469         int left = b.valuesRemainingForDebug();
2470         if (left > 0) {
2471             Utils.log.warning("assertDoneDisbursing: "+left+" values left in "+b);
2472             if (verbose() <= 1)  return false;  // fail now
2473         }
2474         if (b instanceof MultiBand) {
2475             MultiBand mb = (MultiBand) b;
2476             for (int i = 0; i < mb.bandCount; i++) {
2477                 Band sub = mb.bands[i];
2478                 if (sub.phase != DONE_PHASE) {
2479                     Utils.log.warning("assertDoneDisbursing: sub-band still in phase "+sub.phase+": "+sub);
2480                     if (verbose() <= 1)  return false;  // fail now
2481                 }
2482             }
2483         }
2484         return true;
2485     }
2486 
2487     static private void printCDecl(Band b) {
2488         if (b instanceof MultiBand) {
2489             MultiBand mb = (MultiBand) b;
2490             for (int i = 0; i < mb.bandCount; i++) {
2491                 printCDecl(mb.bands[i]);
2492             }
2493             return;
2494         }
2495         String ixS = "NULL";
2496         if (b instanceof CPRefBand) {
2497             Index ix = ((CPRefBand)b).index;
2498             if (ix != null)  ixS = "INDEX("+ix.debugName+")";
2499         }
2500         Coding[] knownc = { BYTE1, CHAR3, BCI5, BRANCH5, UNSIGNED5,
2501                             UDELTA5, SIGNED5, DELTA5, MDELTA5 };
2502         String[] knowns = { "BYTE1", "CHAR3", "BCI5", "BRANCH5", "UNSIGNED5",
2503                             "UDELTA5", "SIGNED5", "DELTA5", "MDELTA5" };
2504         Coding rc = b.regularCoding;
2505         int rci = Arrays.asList(knownc).indexOf(rc);
2506         String cstr;
2507         if (rci >= 0)
2508             cstr = knowns[rci];
2509         else
2510             cstr = "CODING"+rc.keyString();
2511         System.out.println("  BAND_INIT(\""+b.name()+"\""
2512                            +", "+cstr+", "+ixS+"),");
2513     }
2514 
2515     private HashMap prevForAssertMap;
2516 
2517     // DEBUG ONLY:  Record something about the band order.
2518     boolean notePrevForAssert(Band b, Band p) {
2519         if (prevForAssertMap == null)
2520             prevForAssertMap = new HashMap();
2521         prevForAssertMap.put(b, p);
2522         return true;
2523     }
2524 
2525     // DEBUG ONLY:  Validate next input band.
2526     private boolean assertReadyToReadFrom(Band b, InputStream in) throws IOException {
2527         Band p = (Band) prevForAssertMap.get(b);
2528         // Any previous band must be done reading before this one starts.
2529         if (p != null && phaseCmp(p.phase(), DISBURSE_PHASE) < 0) {
2530             Utils.log.warning("Previous band not done reading.");
2531             Utils.log.info("    Previous band: "+p);
2532             Utils.log.info("        Next band: "+b);
2533             Thread.dumpStack();
2534             assert(verbose > 0);  // die unless verbose is true
2535         }
2536         String name = b.name;
2537         if (optDebugBands && !name.startsWith("(")) {
2538             // Verify synchronization between reader & writer:
2539             StringBuffer buf = new StringBuffer();
2540             int ch;
2541             while ((ch = in.read()) > 0)
2542                 buf.append((char)ch);
2543             String inName = buf.toString();
2544             if (!inName.equals(name)) {
2545                 StringBuffer sb = new StringBuffer();
2546                 sb.append("Expected "+name+" but read: ");
2547                 inName += (char)ch;
2548                 while (inName.length() < 10)
2549                     inName += (char)in.read();
2550                 for (int i = 0; i < inName.length(); i++)
2551                     sb.append(inName.charAt(i));
2552                 Utils.log.warning(sb.toString());
2553                 return false;
2554             }
2555         }
2556         return true;
2557     }
2558 
2559     // DEBUG ONLY:  Make sure a bunch of cprefs are correct.
2560     private boolean assertValidCPRefs(CPRefBand b) {
2561         if (b.index == null)  return true;
2562         int limit = b.index.size()+1;
2563         for (int i = 0; i < b.length(); i++) {
2564             int v = b.valueAtForDebug(i);
2565             if (v < 0 || v >= limit) {
2566                 Utils.log.warning("CP ref out of range "+
2567                                    "["+i+"] = "+v+" in "+b);
2568                 return false;
2569             }
2570         }
2571         return true;
2572     }
2573 
2574     // DEBUG ONLY:  Maybe write a debugging cookie to next output band.
2575     private boolean assertReadyToWriteTo(Band b, OutputStream out) throws IOException {
2576         Band p = (Band) prevForAssertMap.get(b);
2577         // Any previous band must be done writing before this one starts.
2578         if (p != null && phaseCmp(p.phase(), DONE_PHASE) < 0) {
2579             Utils.log.warning("Previous band not done writing.");
2580             Utils.log.info("    Previous band: "+p);
2581             Utils.log.info("        Next band: "+b);
2582             Thread.dumpStack();
2583             assert(verbose > 0);  // die unless verbose is true
2584         }
2585         String name = b.name;
2586         if (optDebugBands && !name.startsWith("(")) {
2587             // Verify synchronization between reader & writer:
2588             for (int j = 0; j < name.length(); j++) {
2589                 out.write((byte)name.charAt(j));
2590             }
2591             out.write((byte)0);
2592         }
2593         return true;
2594     }
2595 
2596     protected static boolean testBit(int flags, int bitMask) {
2597         return (flags & bitMask) != 0;
2598     }
2599     protected static int setBit(int flags, int bitMask, boolean z) {
2600         return z ? (flags | bitMask) : (flags &~ bitMask);
2601     }
2602     protected static boolean testBit(long flags, long bitMask) {
2603         return (flags & bitMask) != 0;
2604     }
2605     protected static long setBit(long flags, long bitMask, boolean z) {
2606         return z ? (flags | bitMask) : (flags &~ bitMask);
2607     }
2608 
2609 
2610     static void printArrayTo(PrintStream ps, int[] values, int start, int end) {
2611         int len = end-start;
2612         for (int i = 0; i < len; i++) {
2613             if (i % 10 == 0)
2614                 ps.println();
2615             else
2616                 ps.print(" ");
2617             ps.print(values[start+i]);
2618         }
2619         ps.println();
2620     }
2621 
2622     static void printArrayTo(PrintStream ps, Entry[] cpMap, int start, int end) {
2623         StringBuffer buf = new StringBuffer();
2624         int len = end-start;
2625         for (int i = 0; i < len; i++) {
2626             String s = cpMap[start+i].stringValue();
2627             buf.setLength(0);
2628             for (int j = 0; j < s.length(); j++) {
2629                 char ch = s.charAt(j);
2630                 if (!(ch < ' ' || ch > '~' || ch == '\\')) {
2631                     buf.append(ch);
2632                 } else if (ch == '\n') {
2633                     buf.append("\\n");
2634                 } else if (ch == '\t') {
2635                     buf.append("\\t");
2636                 } else if (ch == '\r') {
2637                     buf.append("\\r");
2638                 } else {
2639                     buf.append("\\x"+Integer.toHexString(ch));
2640                 }
2641             }
2642             ps.println(buf);
2643         }
2644     }
2645 
2646 
2647     // Utilities for reallocating:
2648     protected static Object[] realloc(Object[] a, int len) {
2649         java.lang.Class elt = a.getClass().getComponentType();
2650         Object[] na = (Object[]) java.lang.reflect.Array.newInstance(elt, len);
2651         System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
2652         return na;
2653     }
2654     protected static Object[] realloc(Object[] a) {
2655         return realloc(a, Math.max(10, a.length*2));
2656     }
2657     static private int[] noInts = {};
2658     protected static int[] realloc(int[] a, int len) {
2659         if (len == 0)  return noInts;
2660         if (a == null)  return new int[len];
2661         int[] na = new int[len];
2662         System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
2663         return na;
2664     }
2665     protected static int[] realloc(int[] a) {
2666         return realloc(a, Math.max(10, a.length*2));
2667     }
2668     static private byte[] noBytes = {};
2669     protected static byte[] realloc(byte[] a, int len) {
2670         if (len == 0)  return noBytes;
2671         if (a == null)  return new byte[len];
2672         byte[] na = new byte[len];
2673         System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
2674         return na;
2675     }
2676     protected static byte[] realloc(byte[] a) {
2677         return realloc(a, Math.max(10, a.length*2));
2678     }
2679 }