diff options
Diffstat (limited to 'java/openjdk6/files/icedtea/security/20130201/7186945.patch')
-rw-r--r-- | java/openjdk6/files/icedtea/security/20130201/7186945.patch | 10819 |
1 files changed, 0 insertions, 10819 deletions
diff --git a/java/openjdk6/files/icedtea/security/20130201/7186945.patch b/java/openjdk6/files/icedtea/security/20130201/7186945.patch deleted file mode 100644 index 007ff979f1b7..000000000000 --- a/java/openjdk6/files/icedtea/security/20130201/7186945.patch +++ /dev/null @@ -1,10819 +0,0 @@ -# HG changeset patch -# User miroslawzn -# Date 1354324090 28800 -# Node ID f3f9b711bb1228f4598ded7eb0380c32eba63521 -# Parent 9bbc6817b00c3e9d4eba05d53a8a20b45947ea03 -7186945: Unpack200 improvement -7186957: Improve Pack200 data validation -7186946: Refine unpacker resource usage -Reviewed-by: ksrini - -diff --git a/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java b/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java ---- jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java -+++ jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -22,7 +22,6 @@ - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -- - package com.sun.java.util.jar.pack; - - import java.io.*; -@@ -62,20 +61,20 @@ class BandStructure implements Constants - - /** Call this exactly once, early, to specify the archive major version. */ - public void initPackageMajver(int packageMajver) throws IOException { -- assert(packageMajver > 0 && packageMajver < 0x10000); -- if (this.packageMajver > 0) { -- throw new IOException( -- "Package majver is already initialized to " + this.packageMajver+ -- "; new setting is " + packageMajver); -- } -- this.packageMajver = packageMajver; -- adjustToMajver(); -+ assert(packageMajver > 0 && packageMajver < 0x10000); -+ if (this.packageMajver > 0) { -+ throw new IOException( -+ "Package majver is already initialized to " + this.packageMajver+ -+ "; new setting is " + packageMajver); -+ } -+ this.packageMajver = packageMajver; -+ adjustToMajver(); - } - public int getPackageMajver() { -- if (packageMajver < 0) { -- throw new RuntimeException("Package majver not yet initialized"); -- } -- return packageMajver; -+ if (packageMajver < 0) { -+ throw new RuntimeException("Package majver not yet initialized"); -+ } -+ return packageMajver; - } - - private final boolean isReader = this instanceof PackageReader; -@@ -103,163 +102,163 @@ class BandStructure implements Constants - final static Coding MDELTA5 = Coding.of(5,64,2).getDeltaCoding(); - - final private static Coding[] basicCodings = { -- // Table of "Canonical BHSD Codings" from Pack200 spec. -- null, // _meta_default -+ // Table of "Canonical BHSD Codings" from Pack200 spec. -+ null, // _meta_default - -- // Fixed-length codings: -- Coding.of(1,256,0), -- Coding.of(1,256,1), -- Coding.of(1,256,0).getDeltaCoding(), -- Coding.of(1,256,1).getDeltaCoding(), -- Coding.of(2,256,0), -- Coding.of(2,256,1), -- Coding.of(2,256,0).getDeltaCoding(), -- Coding.of(2,256,1).getDeltaCoding(), -- Coding.of(3,256,0), -- Coding.of(3,256,1), -- Coding.of(3,256,0).getDeltaCoding(), -- Coding.of(3,256,1).getDeltaCoding(), -- Coding.of(4,256,0), -- Coding.of(4,256,1), -- Coding.of(4,256,0).getDeltaCoding(), -- Coding.of(4,256,1).getDeltaCoding(), -+ // Fixed-length codings: -+ Coding.of(1,256,0), -+ Coding.of(1,256,1), -+ Coding.of(1,256,0).getDeltaCoding(), -+ Coding.of(1,256,1).getDeltaCoding(), -+ Coding.of(2,256,0), -+ Coding.of(2,256,1), -+ Coding.of(2,256,0).getDeltaCoding(), -+ Coding.of(2,256,1).getDeltaCoding(), -+ Coding.of(3,256,0), -+ Coding.of(3,256,1), -+ Coding.of(3,256,0).getDeltaCoding(), -+ Coding.of(3,256,1).getDeltaCoding(), -+ Coding.of(4,256,0), -+ Coding.of(4,256,1), -+ Coding.of(4,256,0).getDeltaCoding(), -+ Coding.of(4,256,1).getDeltaCoding(), - -- // Full-range variable-length codings: -- Coding.of(5, 4,0), -- Coding.of(5, 4,1), -- Coding.of(5, 4,2), -- Coding.of(5, 16,0), -- Coding.of(5, 16,1), -- Coding.of(5, 16,2), -- Coding.of(5, 32,0), -- Coding.of(5, 32,1), -- Coding.of(5, 32,2), -- Coding.of(5, 64,0), -- Coding.of(5, 64,1), -- Coding.of(5, 64,2), -- Coding.of(5,128,0), -- Coding.of(5,128,1), -- Coding.of(5,128,2), -+ // Full-range variable-length codings: -+ Coding.of(5, 4,0), -+ Coding.of(5, 4,1), -+ Coding.of(5, 4,2), -+ Coding.of(5, 16,0), -+ Coding.of(5, 16,1), -+ Coding.of(5, 16,2), -+ Coding.of(5, 32,0), -+ Coding.of(5, 32,1), -+ Coding.of(5, 32,2), -+ Coding.of(5, 64,0), -+ Coding.of(5, 64,1), -+ Coding.of(5, 64,2), -+ Coding.of(5,128,0), -+ Coding.of(5,128,1), -+ Coding.of(5,128,2), - -- Coding.of(5, 4,0).getDeltaCoding(), -- Coding.of(5, 4,1).getDeltaCoding(), -- Coding.of(5, 4,2).getDeltaCoding(), -- Coding.of(5, 16,0).getDeltaCoding(), -- Coding.of(5, 16,1).getDeltaCoding(), -- Coding.of(5, 16,2).getDeltaCoding(), -- Coding.of(5, 32,0).getDeltaCoding(), -- Coding.of(5, 32,1).getDeltaCoding(), -- Coding.of(5, 32,2).getDeltaCoding(), -- Coding.of(5, 64,0).getDeltaCoding(), -- Coding.of(5, 64,1).getDeltaCoding(), -- Coding.of(5, 64,2).getDeltaCoding(), -- Coding.of(5,128,0).getDeltaCoding(), -- Coding.of(5,128,1).getDeltaCoding(), -- Coding.of(5,128,2).getDeltaCoding(), -+ Coding.of(5, 4,0).getDeltaCoding(), -+ Coding.of(5, 4,1).getDeltaCoding(), -+ Coding.of(5, 4,2).getDeltaCoding(), -+ Coding.of(5, 16,0).getDeltaCoding(), -+ Coding.of(5, 16,1).getDeltaCoding(), -+ Coding.of(5, 16,2).getDeltaCoding(), -+ Coding.of(5, 32,0).getDeltaCoding(), -+ Coding.of(5, 32,1).getDeltaCoding(), -+ Coding.of(5, 32,2).getDeltaCoding(), -+ Coding.of(5, 64,0).getDeltaCoding(), -+ Coding.of(5, 64,1).getDeltaCoding(), -+ Coding.of(5, 64,2).getDeltaCoding(), -+ Coding.of(5,128,0).getDeltaCoding(), -+ Coding.of(5,128,1).getDeltaCoding(), -+ Coding.of(5,128,2).getDeltaCoding(), - -- // Variable length subrange codings: -- Coding.of(2,192,0), -- Coding.of(2,224,0), -- Coding.of(2,240,0), -- Coding.of(2,248,0), -- Coding.of(2,252,0), -+ // Variable length subrange codings: -+ Coding.of(2,192,0), -+ Coding.of(2,224,0), -+ Coding.of(2,240,0), -+ Coding.of(2,248,0), -+ Coding.of(2,252,0), - -- Coding.of(2, 8,0).getDeltaCoding(), -- Coding.of(2, 8,1).getDeltaCoding(), -- Coding.of(2, 16,0).getDeltaCoding(), -- Coding.of(2, 16,1).getDeltaCoding(), -- Coding.of(2, 32,0).getDeltaCoding(), -- Coding.of(2, 32,1).getDeltaCoding(), -- Coding.of(2, 64,0).getDeltaCoding(), -- Coding.of(2, 64,1).getDeltaCoding(), -- Coding.of(2,128,0).getDeltaCoding(), -- Coding.of(2,128,1).getDeltaCoding(), -- Coding.of(2,192,0).getDeltaCoding(), -- Coding.of(2,192,1).getDeltaCoding(), -- Coding.of(2,224,0).getDeltaCoding(), -- Coding.of(2,224,1).getDeltaCoding(), -- Coding.of(2,240,0).getDeltaCoding(), -- Coding.of(2,240,1).getDeltaCoding(), -- Coding.of(2,248,0).getDeltaCoding(), -- Coding.of(2,248,1).getDeltaCoding(), -+ Coding.of(2, 8,0).getDeltaCoding(), -+ Coding.of(2, 8,1).getDeltaCoding(), -+ Coding.of(2, 16,0).getDeltaCoding(), -+ Coding.of(2, 16,1).getDeltaCoding(), -+ Coding.of(2, 32,0).getDeltaCoding(), -+ Coding.of(2, 32,1).getDeltaCoding(), -+ Coding.of(2, 64,0).getDeltaCoding(), -+ Coding.of(2, 64,1).getDeltaCoding(), -+ Coding.of(2,128,0).getDeltaCoding(), -+ Coding.of(2,128,1).getDeltaCoding(), -+ Coding.of(2,192,0).getDeltaCoding(), -+ Coding.of(2,192,1).getDeltaCoding(), -+ Coding.of(2,224,0).getDeltaCoding(), -+ Coding.of(2,224,1).getDeltaCoding(), -+ Coding.of(2,240,0).getDeltaCoding(), -+ Coding.of(2,240,1).getDeltaCoding(), -+ Coding.of(2,248,0).getDeltaCoding(), -+ Coding.of(2,248,1).getDeltaCoding(), - -- Coding.of(3,192,0), -- Coding.of(3,224,0), -- Coding.of(3,240,0), -- Coding.of(3,248,0), -- Coding.of(3,252,0), -+ Coding.of(3,192,0), -+ Coding.of(3,224,0), -+ Coding.of(3,240,0), -+ Coding.of(3,248,0), -+ Coding.of(3,252,0), - -- Coding.of(3, 8,0).getDeltaCoding(), -- Coding.of(3, 8,1).getDeltaCoding(), -- Coding.of(3, 16,0).getDeltaCoding(), -- Coding.of(3, 16,1).getDeltaCoding(), -- Coding.of(3, 32,0).getDeltaCoding(), -- Coding.of(3, 32,1).getDeltaCoding(), -- Coding.of(3, 64,0).getDeltaCoding(), -- Coding.of(3, 64,1).getDeltaCoding(), -- Coding.of(3,128,0).getDeltaCoding(), -- Coding.of(3,128,1).getDeltaCoding(), -- Coding.of(3,192,0).getDeltaCoding(), -- Coding.of(3,192,1).getDeltaCoding(), -- Coding.of(3,224,0).getDeltaCoding(), -- Coding.of(3,224,1).getDeltaCoding(), -- Coding.of(3,240,0).getDeltaCoding(), -- Coding.of(3,240,1).getDeltaCoding(), -- Coding.of(3,248,0).getDeltaCoding(), -- Coding.of(3,248,1).getDeltaCoding(), -+ Coding.of(3, 8,0).getDeltaCoding(), -+ Coding.of(3, 8,1).getDeltaCoding(), -+ Coding.of(3, 16,0).getDeltaCoding(), -+ Coding.of(3, 16,1).getDeltaCoding(), -+ Coding.of(3, 32,0).getDeltaCoding(), -+ Coding.of(3, 32,1).getDeltaCoding(), -+ Coding.of(3, 64,0).getDeltaCoding(), -+ Coding.of(3, 64,1).getDeltaCoding(), -+ Coding.of(3,128,0).getDeltaCoding(), -+ Coding.of(3,128,1).getDeltaCoding(), -+ Coding.of(3,192,0).getDeltaCoding(), -+ Coding.of(3,192,1).getDeltaCoding(), -+ Coding.of(3,224,0).getDeltaCoding(), -+ Coding.of(3,224,1).getDeltaCoding(), -+ Coding.of(3,240,0).getDeltaCoding(), -+ Coding.of(3,240,1).getDeltaCoding(), -+ Coding.of(3,248,0).getDeltaCoding(), -+ Coding.of(3,248,1).getDeltaCoding(), - -- Coding.of(4,192,0), -- Coding.of(4,224,0), -- Coding.of(4,240,0), -- Coding.of(4,248,0), -- Coding.of(4,252,0), -+ Coding.of(4,192,0), -+ Coding.of(4,224,0), -+ Coding.of(4,240,0), -+ Coding.of(4,248,0), -+ Coding.of(4,252,0), - -- Coding.of(4, 8,0).getDeltaCoding(), -- Coding.of(4, 8,1).getDeltaCoding(), -- Coding.of(4, 16,0).getDeltaCoding(), -- Coding.of(4, 16,1).getDeltaCoding(), -- Coding.of(4, 32,0).getDeltaCoding(), -- Coding.of(4, 32,1).getDeltaCoding(), -- Coding.of(4, 64,0).getDeltaCoding(), -- Coding.of(4, 64,1).getDeltaCoding(), -- Coding.of(4,128,0).getDeltaCoding(), -- Coding.of(4,128,1).getDeltaCoding(), -- Coding.of(4,192,0).getDeltaCoding(), -- Coding.of(4,192,1).getDeltaCoding(), -- Coding.of(4,224,0).getDeltaCoding(), -- Coding.of(4,224,1).getDeltaCoding(), -- Coding.of(4,240,0).getDeltaCoding(), -- Coding.of(4,240,1).getDeltaCoding(), -- Coding.of(4,248,0).getDeltaCoding(), -- Coding.of(4,248,1).getDeltaCoding(), -+ Coding.of(4, 8,0).getDeltaCoding(), -+ Coding.of(4, 8,1).getDeltaCoding(), -+ Coding.of(4, 16,0).getDeltaCoding(), -+ Coding.of(4, 16,1).getDeltaCoding(), -+ Coding.of(4, 32,0).getDeltaCoding(), -+ Coding.of(4, 32,1).getDeltaCoding(), -+ Coding.of(4, 64,0).getDeltaCoding(), -+ Coding.of(4, 64,1).getDeltaCoding(), -+ Coding.of(4,128,0).getDeltaCoding(), -+ Coding.of(4,128,1).getDeltaCoding(), -+ Coding.of(4,192,0).getDeltaCoding(), -+ Coding.of(4,192,1).getDeltaCoding(), -+ Coding.of(4,224,0).getDeltaCoding(), -+ Coding.of(4,224,1).getDeltaCoding(), -+ Coding.of(4,240,0).getDeltaCoding(), -+ Coding.of(4,240,1).getDeltaCoding(), -+ Coding.of(4,248,0).getDeltaCoding(), -+ Coding.of(4,248,1).getDeltaCoding(), - -- null -+ null - }; - final private static HashMap basicCodingIndexes; - static { -- assert(basicCodings[_meta_default] == null); -- assert(basicCodings[_meta_canon_min] != null); -- assert(basicCodings[_meta_canon_max] != null); -- HashMap map = new HashMap(); -- for (int i = 0; i < basicCodings.length; i++) { -- Coding c = basicCodings[i]; -- if (c == null) continue; -- assert(i >= _meta_canon_min); -- assert(i <= _meta_canon_max); -- map.put(c, new Integer(i)); -- } -- basicCodingIndexes = map; -+ assert(basicCodings[_meta_default] == null); -+ assert(basicCodings[_meta_canon_min] != null); -+ assert(basicCodings[_meta_canon_max] != null); -+ HashMap map = new HashMap(); -+ for (int i = 0; i < basicCodings.length; i++) { -+ Coding c = basicCodings[i]; -+ if (c == null) continue; -+ assert(i >= _meta_canon_min); -+ assert(i <= _meta_canon_max); -+ map.put(c, new Integer(i)); -+ } -+ basicCodingIndexes = map; - } - public static Coding codingForIndex(int i) { -- return i < basicCodings.length ? basicCodings[i] : null; -+ return i < basicCodings.length ? basicCodings[i] : null; - } - public static int indexOf(Coding c) { -- Integer i = (Integer) basicCodingIndexes.get(c); -- if (i == null) return 0; -- return i.intValue(); -+ Integer i = (Integer) basicCodingIndexes.get(c); -+ if (i == null) return 0; -+ return i.intValue(); - } - public static Coding[] getBasicCodings() { -- return (Coding[]) basicCodings.clone(); -+ return (Coding[]) basicCodings.clone(); - } - - protected byte[] bandHeaderBytes; // used for input only -@@ -267,31 +266,31 @@ class BandStructure implements Constants - protected int bandHeaderBytePos0; // for debug - - protected CodingMethod getBandHeader(int XB, Coding regularCoding) { -- CodingMethod[] res = {null}; -- // push back XB onto the band header bytes -- bandHeaderBytes[--bandHeaderBytePos] = (byte) XB; -- bandHeaderBytePos0 = bandHeaderBytePos; -- // scan forward through XB and any additional band header bytes -- bandHeaderBytePos = parseMetaCoding(bandHeaderBytes, -- bandHeaderBytePos, -- regularCoding, -- res); -- return res[0]; -+ CodingMethod[] res = {null}; -+ // push back XB onto the band header bytes -+ bandHeaderBytes[--bandHeaderBytePos] = (byte) XB; -+ bandHeaderBytePos0 = bandHeaderBytePos; -+ // scan forward through XB and any additional band header bytes -+ bandHeaderBytePos = parseMetaCoding(bandHeaderBytes, -+ bandHeaderBytePos, -+ regularCoding, -+ res); -+ return res[0]; - } - - public static int parseMetaCoding(byte[] bytes, int pos, Coding dflt, CodingMethod[] res) { -- if ((bytes[pos] & 0xFF) == _meta_default) { -- res[0] = dflt; -- return pos+1; -- } -- int pos2; -- pos2 = Coding.parseMetaCoding(bytes, pos, dflt, res); -- if (pos2 > pos) return pos2; -- pos2 = PopulationCoding.parseMetaCoding(bytes, pos, dflt, res); -- if (pos2 > pos) return pos2; -- pos2 = AdaptiveCoding.parseMetaCoding(bytes, pos, dflt, res); -- if (pos2 > pos) return pos2; -- throw new RuntimeException("Bad meta-coding op "+(bytes[pos]&0xFF)); -+ if ((bytes[pos] & 0xFF) == _meta_default) { -+ res[0] = dflt; -+ return pos+1; -+ } -+ int pos2; -+ pos2 = Coding.parseMetaCoding(bytes, pos, dflt, res); -+ if (pos2 > pos) return pos2; -+ pos2 = PopulationCoding.parseMetaCoding(bytes, pos, dflt, res); -+ if (pos2 > pos) return pos2; -+ pos2 = AdaptiveCoding.parseMetaCoding(bytes, pos, dflt, res); -+ if (pos2 > pos) return pos2; -+ throw new RuntimeException("Bad meta-coding op "+(bytes[pos]&0xFF)); - } - - static final int SHORT_BAND_HEURISTIC = 100; -@@ -311,11 +310,11 @@ class BandStructure implements Constants - public static final int DONE_PHASE = 8; // done writing or reading - - static boolean phaseIsRead(int p) { -- return (p % 2) == 0; -+ return (p % 2) == 0; - } - static int phaseCmp(int p0, int p1) { -- assert((p0 % 2) == (p1 % 2) || (p0 % 8) == 0 || (p1 % 8) == 0); -- return p0 - p1; -+ assert((p0 % 2) == (p1 % 2) || (p0 % 8) == 0 || (p1 % 8) == 0); -+ return p0 - p1; - } - - /** The packed file is divided up into a number of segments. -@@ -332,7 +331,7 @@ class BandStructure implements Constants - * - * The three phases for reading a packed file are EXPECT, READ, - * and DISBURSE. -- * 1. For each band, the expected number of integers is determined. -+ * 1. For each band, the expected number of integers is determined. - * 2. The data is actually read from the file into the band. - * 3. The band pays out its values as requested, in an ad hoc order. - * -@@ -340,696 +339,695 @@ class BandStructure implements Constants - * Clearly, these phases must be properly ordered WRT each other. - */ - abstract class Band { -- private int phase = NO_PHASE; -- private final String name; -+ private int phase = NO_PHASE; -+ private final String name; - -- private int valuesExpected; -+ private int valuesExpected; - -- protected long outputSize = -1; // cache -+ protected long outputSize = -1; // cache - -- final public Coding regularCoding; -+ final public Coding regularCoding; - -- final public int seqForDebug; -- public int elementCountForDebug; -+ final public int seqForDebug; -+ public int elementCountForDebug; - - -- protected Band(String name, Coding regularCoding) { -- this.name = name; -- this.regularCoding = regularCoding; -- this.seqForDebug = ++nextSeqForDebug; -- if (verbose > 2) -- Utils.log.fine("Band "+seqForDebug+" is "+name); -- // caller must call init -- } -+ protected Band(String name, Coding regularCoding) { -+ this.name = name; -+ this.regularCoding = regularCoding; -+ this.seqForDebug = ++nextSeqForDebug; -+ if (verbose > 2) -+ Utils.log.fine("Band "+seqForDebug+" is "+name); -+ // caller must call init -+ } - -- public Band init() { -- // Cannot due this from the constructor, because constructor -- // may wish to initialize some subclass variables. -- // Set initial phase for reading or writing: -- if (isReader) -- readyToExpect(); -- else -- readyToCollect(); -- return this; -- } -+ public Band init() { -+ // Cannot due this from the constructor, because constructor -+ // may wish to initialize some subclass variables. -+ // Set initial phase for reading or writing: -+ if (isReader) -+ readyToExpect(); -+ else -+ readyToCollect(); -+ return this; -+ } - -- // common operations -- boolean isReader() { return isReader; } -- int phase() { return phase; } -- String name() { return name; } -+ // common operations -+ boolean isReader() { return isReader; } -+ int phase() { return phase; } -+ String name() { return name; } - -- /** Return -1 if data buffer not allocated, else max length. */ -- public abstract int capacity(); -+ /** Return -1 if data buffer not allocated, else max length. */ -+ public abstract int capacity(); - -- /** Allocate data buffer to specified length. */ -- protected abstract void setCapacity(int cap); -+ /** Allocate data buffer to specified length. */ -+ protected abstract void setCapacity(int cap); - -- /** Return current number of values in buffer, which must exist. */ -- public abstract int length(); -+ /** Return current number of values in buffer, which must exist. */ -+ public abstract int length(); - -- protected abstract int valuesRemainingForDebug(); -+ protected abstract int valuesRemainingForDebug(); - -- public final int valuesExpected() { -- return valuesExpected; -- } -+ public final int valuesExpected() { -+ return valuesExpected; -+ } - -- /** Write out bytes, encoding the values. */ -- public final void writeTo(OutputStream out) throws IOException { -- assert(assertReadyToWriteTo(this, out)); -- setPhase(WRITE_PHASE); -- // subclasses continue by writing their contents to output -- writeDataTo(out); -- doneWriting(); -- } -+ /** Write out bytes, encoding the values. */ -+ public final void writeTo(OutputStream out) throws IOException { -+ assert(assertReadyToWriteTo(this, out)); -+ setPhase(WRITE_PHASE); -+ // subclasses continue by writing their contents to output -+ writeDataTo(out); -+ doneWriting(); -+ } - -- abstract void chooseBandCodings() throws IOException; -+ abstract void chooseBandCodings() throws IOException; - -- public final long outputSize() { -- if (outputSize >= 0) { -- long size = outputSize; -- assert(size == computeOutputSize()); -- return size; -- } -- return computeOutputSize(); -- } -+ public final long outputSize() { -+ if (outputSize >= 0) { -+ long size = outputSize; -+ assert(size == computeOutputSize()); -+ return size; -+ } -+ return computeOutputSize(); -+ } - -- protected abstract long computeOutputSize(); -+ protected abstract long computeOutputSize(); - -- abstract protected void writeDataTo(OutputStream out) throws IOException; -+ abstract protected void writeDataTo(OutputStream out) throws IOException; - -- /** Expect a certain number of values. */ -- void expectLength(int l) { -- assert(assertPhase(this, EXPECT_PHASE)); -- assert(valuesExpected == 0); // all at once -- assert(l >= 0); -- valuesExpected = l; -- } -- /** Expect more values. (Multiple calls accumulate.) */ -- void expectMoreLength(int l) { -- assert(assertPhase(this, EXPECT_PHASE)); -- valuesExpected += l; -- } -+ /** Expect a certain number of values. */ -+ void expectLength(int l) { -+ assert(assertPhase(this, EXPECT_PHASE)); -+ assert(valuesExpected == 0); // all at once -+ assert(l >= 0); -+ valuesExpected = l; -+ } -+ /** Expect more values. (Multiple calls accumulate.) */ -+ void expectMoreLength(int l) { -+ assert(assertPhase(this, EXPECT_PHASE)); -+ valuesExpected += l; -+ } - - -- /// Phase change markers. -+ /// Phase change markers. - -- private void readyToCollect() { // called implicitly by constructor -- setCapacity(1); -- setPhase(COLLECT_PHASE); -- } -- protected void doneWriting() { -- assert(assertPhase(this, WRITE_PHASE)); -- setPhase(DONE_PHASE); -- } -- private void readyToExpect() { // called implicitly by constructor -- setPhase(EXPECT_PHASE); -- } -- /** Read in bytes, decoding the values. */ -- public final void readFrom(InputStream in) throws IOException { -- assert(assertReadyToReadFrom(this, in)); -- setCapacity(valuesExpected()); -- setPhase(READ_PHASE); -- // subclasses continue by reading their contents from input: -- readDataFrom(in); -- readyToDisburse(); -- } -- abstract protected void readDataFrom(InputStream in) throws IOException; -- protected void readyToDisburse() { -- if (verbose > 1) Utils.log.fine("readyToDisburse "+this); -- setPhase(DISBURSE_PHASE); -- } -- public void doneDisbursing() { -- assert(assertPhase(this, DISBURSE_PHASE)); -- setPhase(DONE_PHASE); -- } -- public final void doneWithUnusedBand() { -- if (isReader) { -- assert(assertPhase(this, EXPECT_PHASE)); -- assert(valuesExpected() == 0); -- // Fast forward: -- setPhase(READ_PHASE); -- setPhase(DISBURSE_PHASE); -- setPhase(DONE_PHASE); -- } else { -- setPhase(FROZEN_PHASE); -- } -- } -+ private void readyToCollect() { // called implicitly by constructor -+ setCapacity(1); -+ setPhase(COLLECT_PHASE); -+ } -+ protected void doneWriting() { -+ assert(assertPhase(this, WRITE_PHASE)); -+ setPhase(DONE_PHASE); -+ } -+ private void readyToExpect() { // called implicitly by constructor -+ setPhase(EXPECT_PHASE); -+ } -+ /** Read in bytes, decoding the values. */ -+ public final void readFrom(InputStream in) throws IOException { -+ assert(assertReadyToReadFrom(this, in)); -+ setCapacity(valuesExpected()); -+ setPhase(READ_PHASE); -+ // subclasses continue by reading their contents from input: -+ readDataFrom(in); -+ readyToDisburse(); -+ } -+ abstract protected void readDataFrom(InputStream in) throws IOException; -+ protected void readyToDisburse() { -+ if (verbose > 1) Utils.log.fine("readyToDisburse "+this); -+ setPhase(DISBURSE_PHASE); -+ } -+ public void doneDisbursing() { -+ assert(assertPhase(this, DISBURSE_PHASE)); -+ setPhase(DONE_PHASE); -+ } -+ public final void doneWithUnusedBand() { -+ if (isReader) { -+ assert(assertPhase(this, EXPECT_PHASE)); -+ assert(valuesExpected() == 0); -+ // Fast forward: -+ setPhase(READ_PHASE); -+ setPhase(DISBURSE_PHASE); -+ setPhase(DONE_PHASE); -+ } else { -+ setPhase(FROZEN_PHASE); -+ } -+ } - -- protected void setPhase(int newPhase) { -- assert(assertPhaseChangeOK(this, phase, newPhase)); -- this.phase = newPhase; -- } -+ protected void setPhase(int newPhase) { -+ assert(assertPhaseChangeOK(this, phase, newPhase)); -+ this.phase = newPhase; -+ } - -- protected int lengthForDebug = -1; // DEBUG ONLY -- public String toString() { // DEBUG ONLY -- int length = (lengthForDebug != -1 ? lengthForDebug : length()); -- String str = name; -- if (length != 0) -- str += "[" + length + "]"; -- if (elementCountForDebug != 0) -- str += "(" + elementCountForDebug + ")"; -- return str; -- } -+ protected int lengthForDebug = -1; // DEBUG ONLY -+ public String toString() { // DEBUG ONLY -+ int length = (lengthForDebug != -1 ? lengthForDebug : length()); -+ String str = name; -+ if (length != 0) -+ str += "[" + length + "]"; -+ if (elementCountForDebug != 0) -+ str += "(" + elementCountForDebug + ")"; -+ return str; -+ } - } - - class ValueBand extends Band { -- private int[] values; // must be null in EXPECT phase -- private int length; -- private int valuesDisbursed; -+ private int[] values; // must be null in EXPECT phase -+ private int length; -+ private int valuesDisbursed; - -- private CodingMethod bandCoding; -- private byte[] metaCoding; -+ private CodingMethod bandCoding; -+ private byte[] metaCoding; - -- protected ValueBand(String name, Coding regularCoding) { -- super(name, regularCoding); -- } -+ protected ValueBand(String name, Coding regularCoding) { -+ super(name, regularCoding); -+ } - -- public int capacity() { -- return values == null ? -1 : values.length; -- } -+ public int capacity() { -+ return values == null ? -1 : values.length; -+ } - -- /** Declare predicted or needed capacity. */ -- protected void setCapacity(int cap) { -- assert(length <= cap); -- if (cap == -1) { values = null; return; } -- values = realloc(values, cap); -- } -+ /** Declare predicted or needed capacity. */ -+ protected void setCapacity(int cap) { -+ assert(length <= cap); -+ if (cap == -1) { values = null; return; } -+ values = realloc(values, cap); -+ } - -- public int length() { -- return length; -- } -- protected int valuesRemainingForDebug() { -- return length - valuesDisbursed; -- } -- protected int valueAtForDebug(int i) { -- return values[i]; -- } -+ public int length() { -+ return length; -+ } -+ protected int valuesRemainingForDebug() { -+ return length - valuesDisbursed; -+ } -+ protected int valueAtForDebug(int i) { -+ return values[i]; -+ } - -- void patchValue(int i, int value) { -- // Only one use for this. -- assert(this == archive_header_S); -- assert(i == AH_ARCHIVE_SIZE_HI || i == AH_ARCHIVE_SIZE_LO); -- assert(i < length); // must have already output a dummy -- values[i] = value; -- outputSize = -1; // decache -- } -+ void patchValue(int i, int value) { -+ // Only one use for this. -+ assert(this == archive_header_S); -+ assert(i == AH_ARCHIVE_SIZE_HI || i == AH_ARCHIVE_SIZE_LO); -+ assert(i < length); // must have already output a dummy -+ values[i] = value; -+ outputSize = -1; // decache -+ } - -- protected void initializeValues(int[] values) { -- assert(assertCanChangeLength(this)); -- assert(length == 0); -- this.values = values; -- this.length = values.length; -- } -+ protected void initializeValues(int[] values) { -+ assert(assertCanChangeLength(this)); -+ assert(length == 0); -+ this.values = values; -+ this.length = values.length; -+ } - -- /** Collect one value, or store one decoded value. */ -- protected void addValue(int x) { -- assert(assertCanChangeLength(this)); -- if (length == values.length) -- setCapacity(length < 1000 ? length * 10 : length * 2); -- values[length++] = x; -- } -+ /** Collect one value, or store one decoded value. */ -+ protected void addValue(int x) { -+ assert(assertCanChangeLength(this)); -+ if (length == values.length) -+ setCapacity(length < 1000 ? length * 10 : length * 2); -+ values[length++] = x; -+ } - -- private boolean canVaryCoding() { -- if (!optVaryCodings) return false; -- if (length == 0) return false; -- // Can't read band_headers w/o the archive header: -- if (this == archive_header_0) return false; -- if (this == archive_header_S) return false; -- if (this == archive_header_1) return false; -- // BYTE1 bands can't vary codings, but the others can. -- // All that's needed for the initial escape is at least -- // 256 negative values or more than 256 non-negative values -- return (regularCoding.min() <= -256 || regularCoding.max() >= 256); -- } -+ private boolean canVaryCoding() { -+ if (!optVaryCodings) return false; -+ if (length == 0) return false; -+ // Can't read band_headers w/o the archive header: -+ if (this == archive_header_0) return false; -+ if (this == archive_header_S) return false; -+ if (this == archive_header_1) return false; -+ // BYTE1 bands can't vary codings, but the others can. -+ // All that's needed for the initial escape is at least -+ // 256 negative values or more than 256 non-negative values -+ return (regularCoding.min() <= -256 || regularCoding.max() >= 256); -+ } - -- private boolean shouldVaryCoding() { -- assert(canVaryCoding()); -- if (effort < MAX_EFFORT && length < SHORT_BAND_HEURISTIC) -- return false; -- return true; -- } -+ private boolean shouldVaryCoding() { -+ assert(canVaryCoding()); -+ if (effort < MAX_EFFORT && length < SHORT_BAND_HEURISTIC) -+ return false; -+ return true; -+ } - -- protected void chooseBandCodings() throws IOException { -- boolean canVary = canVaryCoding(); -- if (!canVary || !shouldVaryCoding()) { -- if (regularCoding.canRepresent(values, 0, length)) { -- bandCoding = regularCoding; -- } else { -- assert(canVary); -- if (verbose > 1) -- Utils.log.fine("regular coding fails in band "+name()); -- bandCoding = UNSIGNED5; -- } -- outputSize = -1; -- } else { -- int[] sizes = {0,0}; -- bandCoding = chooseCoding(values, 0, length, -- regularCoding, name(), -- sizes); -- outputSize = sizes[CodingChooser.BYTE_SIZE]; -- if (outputSize == 0) // CodingChooser failed to size it. -- outputSize = -1; -- } -+ protected void chooseBandCodings() throws IOException { -+ boolean canVary = canVaryCoding(); -+ if (!canVary || !shouldVaryCoding()) { -+ if (regularCoding.canRepresent(values, 0, length)) { -+ bandCoding = regularCoding; -+ } else { -+ assert(canVary); -+ if (verbose > 1) -+ Utils.log.fine("regular coding fails in band "+name()); -+ bandCoding = UNSIGNED5; -+ } -+ outputSize = -1; -+ } else { -+ int[] sizes = {0,0}; -+ bandCoding = chooseCoding(values, 0, length, -+ regularCoding, name(), -+ sizes); -+ outputSize = sizes[CodingChooser.BYTE_SIZE]; -+ if (outputSize == 0) // CodingChooser failed to size it. -+ outputSize = -1; -+ } - -- // Compute and save the meta-coding bytes also. -- if (bandCoding != regularCoding) { -- metaCoding = bandCoding.getMetaCoding(regularCoding); -- if (verbose > 1) { -- Utils.log.fine("alternate coding "+this+" "+bandCoding); -- } -- } else if (canVary && -- decodeEscapeValue(values[0], regularCoding) >= 0) { -- // Need an explicit default. -- metaCoding = defaultMetaCoding; -- } else { -- // Common case: Zero bytes of meta coding. -- metaCoding = noMetaCoding; -- } -- if (metaCoding.length > 0 -- && (verbose > 2 || verbose > 1 && metaCoding.length > 1)) { -- StringBuffer sb = new StringBuffer(); -- for (int i = 0; i < metaCoding.length; i++) { -- if (i == 1) sb.append(" /"); -- sb.append(" ").append(metaCoding[i] & 0xFF); -- } -- Utils.log.fine(" meta-coding "+sb); -- } -+ // Compute and save the meta-coding bytes also. -+ if (bandCoding != regularCoding) { -+ metaCoding = bandCoding.getMetaCoding(regularCoding); -+ if (verbose > 1) { -+ Utils.log.fine("alternate coding "+this+" "+bandCoding); -+ } -+ } else if (canVary && -+ decodeEscapeValue(values[0], regularCoding) >= 0) { -+ // Need an explicit default. -+ metaCoding = defaultMetaCoding; -+ } else { -+ // Common case: Zero bytes of meta coding. -+ metaCoding = noMetaCoding; -+ } -+ if (metaCoding.length > 0 -+ && (verbose > 2 || verbose > 1 && metaCoding.length > 1)) { -+ StringBuffer sb = new StringBuffer(); -+ for (int i = 0; i < metaCoding.length; i++) { -+ if (i == 1) sb.append(" /"); -+ sb.append(" ").append(metaCoding[i] & 0xFF); -+ } -+ Utils.log.fine(" meta-coding "+sb); -+ } - -- assert((outputSize < 0) || -- !(bandCoding instanceof Coding) || -- (outputSize == ((Coding)bandCoding) -- .getLength(values, 0, length))) -- : (bandCoding+" : "+ -- outputSize+" != "+ -- ((Coding)bandCoding).getLength(values, 0, length) -- +" ?= "+getCodingChooser().computeByteSize(bandCoding,values,0,length) -- ); -+ assert((outputSize < 0) || -+ !(bandCoding instanceof Coding) || -+ (outputSize == ((Coding)bandCoding) -+ .getLength(values, 0, length))) -+ : (bandCoding+" : "+ -+ outputSize+" != "+ -+ ((Coding)bandCoding).getLength(values, 0, length) -+ +" ?= "+getCodingChooser().computeByteSize(bandCoding,values,0,length) -+ ); - -- // Compute outputSize of the escape value X, if any. -- if (metaCoding.length > 0) { -- // First byte XB of meta-coding is treated specially, -- // but any other bytes go into the band headers band. -- // This must be done before any other output happens. -- if (outputSize >= 0) -- outputSize += computeEscapeSize(); // good cache -- // Other bytes go into band_headers. -- for (int i = 1; i < metaCoding.length; i++) { -- band_headers.putByte(metaCoding[i] & 0xFF); -- } -- } -- } -+ // Compute outputSize of the escape value X, if any. -+ if (metaCoding.length > 0) { -+ // First byte XB of meta-coding is treated specially, -+ // but any other bytes go into the band headers band. -+ // This must be done before any other output happens. -+ if (outputSize >= 0) -+ outputSize += computeEscapeSize(); // good cache -+ // Other bytes go into band_headers. -+ for (int i = 1; i < metaCoding.length; i++) { -+ band_headers.putByte(metaCoding[i] & 0xFF); -+ } -+ } -+ } - -- protected long computeOutputSize() { -- outputSize = getCodingChooser().computeByteSize(bandCoding, -- values, 0, length); -- assert(outputSize < Integer.MAX_VALUE); -- outputSize += computeEscapeSize(); -- return outputSize; -- } -+ protected long computeOutputSize() { -+ outputSize = getCodingChooser().computeByteSize(bandCoding, -+ values, 0, length); -+ assert(outputSize < Integer.MAX_VALUE); -+ outputSize += computeEscapeSize(); -+ return outputSize; -+ } - -- protected int computeEscapeSize() { -- if (metaCoding.length == 0) return 0; -- int XB = metaCoding[0] & 0xFF; -- int X = encodeEscapeValue(XB, regularCoding); -- return regularCoding.setD(0).getLength(X); -- } -+ protected int computeEscapeSize() { -+ if (metaCoding.length == 0) return 0; -+ int XB = metaCoding[0] & 0xFF; -+ int X = encodeEscapeValue(XB, regularCoding); -+ return regularCoding.setD(0).getLength(X); -+ } - -- protected void writeDataTo(OutputStream out) throws IOException { -- if (length == 0) return; // nothing to write -- long len0 = 0; -- if (out == outputCounter) { -- len0 = outputCounter.getCount(); -- } -- if (metaCoding.length > 0) { -- int XB = metaCoding[0] & 0xFF; -- // We need an explicit band header, either because -- // there is a non-default coding method, or because -- // the first value would be parsed as an escape value. -- int X = encodeEscapeValue(XB, regularCoding); -- //System.out.println("X="+X+" XB="+XB+" in "+this); -- regularCoding.setD(0).writeTo(out, X); -- } -- bandCoding.writeArrayTo(out, values, 0, length); -- if (out == outputCounter) { -- long len1 = outputCounter.getCount(); -- assert(outputSize == outputCounter.getCount() - len0) -- : (outputSize+" != "+outputCounter.getCount()+"-"+len0); -- } -- if (optDumpBands) dumpBand(); -- } -+ protected void writeDataTo(OutputStream out) throws IOException { -+ if (length == 0) return; // nothing to write -+ long len0 = 0; -+ if (out == outputCounter) { -+ len0 = outputCounter.getCount(); -+ } -+ if (metaCoding.length > 0) { -+ int XB = metaCoding[0] & 0xFF; -+ // We need an explicit band header, either because -+ // there is a non-default coding method, or because -+ // the first value would be parsed as an escape value. -+ int X = encodeEscapeValue(XB, regularCoding); -+ //System.out.println("X="+X+" XB="+XB+" in "+this); -+ regularCoding.setD(0).writeTo(out, X); -+ } -+ bandCoding.writeArrayTo(out, values, 0, length); -+ if (out == outputCounter) { -+ long len1 = outputCounter.getCount(); -+ assert(outputSize == outputCounter.getCount() - len0) -+ : (outputSize+" != "+outputCounter.getCount()+"-"+len0); -+ } -+ if (optDumpBands) dumpBand(); -+ } - -- protected void readDataFrom(InputStream in) throws IOException { -- length = valuesExpected(); -- if (length == 0) return; // nothing to read -- if (verbose > 1) -- Utils.log.fine("Reading band "+this); -- if (!canVaryCoding()) { -- bandCoding = regularCoding; -- metaCoding = noMetaCoding; -- } else { -- assert(in.markSupported()); // input must be buffered -- in.mark(Coding.B_MAX); -- int X = regularCoding.setD(0).readFrom(in); -- int XB = decodeEscapeValue(X, regularCoding); -- if (XB < 0) { -- // Do not consume this value. No alternate coding. -- in.reset(); -- XB = _meta_default; -- bandCoding = regularCoding; -- metaCoding = noMetaCoding; -- } else if (XB == _meta_default) { -- bandCoding = regularCoding; -- metaCoding = defaultMetaCoding; -- } else { -- if (verbose > 2) -- Utils.log.fine("found X="+X+" => XB="+XB); -- bandCoding = getBandHeader(XB, regularCoding); -- // This is really used only by dumpBands. -- int p0 = bandHeaderBytePos0; -- int p1 = bandHeaderBytePos; -- metaCoding = new byte[p1-p0]; -- System.arraycopy(bandHeaderBytes, p0, -- metaCoding, 0, metaCoding.length); -- } -- } -- if (bandCoding != regularCoding) { -- if (verbose > 1) -- Utils.log.fine(name()+": irregular coding "+bandCoding); -- } -- bandCoding.readArrayFrom(in, values, 0, length); -- if (optDumpBands) dumpBand(); -- } -+ protected void readDataFrom(InputStream in) throws IOException { -+ length = valuesExpected(); -+ if (length == 0) return; // nothing to read -+ if (verbose > 1) -+ Utils.log.fine("Reading band "+this); -+ if (!canVaryCoding()) { -+ bandCoding = regularCoding; -+ metaCoding = noMetaCoding; -+ } else { -+ assert(in.markSupported()); // input must be buffered -+ in.mark(Coding.B_MAX); -+ int X = regularCoding.setD(0).readFrom(in); -+ int XB = decodeEscapeValue(X, regularCoding); -+ if (XB < 0) { -+ // Do not consume this value. No alternate coding. -+ in.reset(); -+ XB = _meta_default; -+ bandCoding = regularCoding; -+ metaCoding = noMetaCoding; -+ } else if (XB == _meta_default) { -+ bandCoding = regularCoding; -+ metaCoding = defaultMetaCoding; -+ } else { -+ if (verbose > 2) -+ Utils.log.fine("found X="+X+" => XB="+XB); -+ bandCoding = getBandHeader(XB, regularCoding); -+ // This is really used only by dumpBands. -+ int p0 = bandHeaderBytePos0; -+ int p1 = bandHeaderBytePos; -+ metaCoding = new byte[p1-p0]; -+ System.arraycopy(bandHeaderBytes, p0, -+ metaCoding, 0, metaCoding.length); -+ } -+ } -+ if (bandCoding != regularCoding) { -+ if (verbose > 1) -+ Utils.log.fine(name()+": irregular coding "+bandCoding); -+ } -+ bandCoding.readArrayFrom(in, values, 0, length); -+ if (optDumpBands) dumpBand(); -+ } - -- public void doneDisbursing() { -- super.doneDisbursing(); -- values = null; // for GC -- } -+ public void doneDisbursing() { -+ super.doneDisbursing(); -+ values = null; // for GC -+ } - -- private void dumpBand() throws IOException { -- assert(optDumpBands); -- PrintStream ps = new PrintStream(getDumpStream(this, ".txt")); -- String irr = (bandCoding == regularCoding) ? "" : " irregular"; -- ps.print("# length="+length+ -- " size="+outputSize()+ -- irr+" coding="+bandCoding); -- if (metaCoding != noMetaCoding) { -- StringBuffer sb = new StringBuffer(); -- for (int i = 0; i < metaCoding.length; i++) { -- if (i == 1) sb.append(" /"); -- sb.append(" ").append(metaCoding[i] & 0xFF); -- } -- ps.print(" //header: "+sb); -- } -- printArrayTo(ps, values, 0, length); -- ps.close(); -- OutputStream ds = getDumpStream(this, ".bnd"); -- bandCoding.writeArrayTo(ds, values, 0, length); -- ds.close(); -- } -+ private void dumpBand() throws IOException { -+ assert(optDumpBands); -+ PrintStream ps = new PrintStream(getDumpStream(this, ".txt")); -+ String irr = (bandCoding == regularCoding) ? "" : " irregular"; -+ ps.print("# length="+length+ -+ " size="+outputSize()+ -+ irr+" coding="+bandCoding); -+ if (metaCoding != noMetaCoding) { -+ StringBuffer sb = new StringBuffer(); -+ for (int i = 0; i < metaCoding.length; i++) { -+ if (i == 1) sb.append(" /"); -+ sb.append(" ").append(metaCoding[i] & 0xFF); -+ } -+ ps.print(" //header: "+sb); -+ } -+ printArrayTo(ps, values, 0, length); -+ ps.close(); -+ OutputStream ds = getDumpStream(this, ".bnd"); -+ bandCoding.writeArrayTo(ds, values, 0, length); -+ ds.close(); -+ } - -- /** Disburse one value. */ -- protected int getValue() { -- assert(phase() == DISBURSE_PHASE); -- assert(valuesDisbursed < length); -- return values[valuesDisbursed++]; -- } -+ /** Disburse one value. */ -+ protected int getValue() { -+ assert(phase() == DISBURSE_PHASE); -+ assert(valuesDisbursed < length); -+ return values[valuesDisbursed++]; -+ } - -- /** Reset for another pass over the same value set. */ -- public void resetForSecondPass() { -- assert(phase() == DISBURSE_PHASE); -- assert(valuesDisbursed == length()); // 1st pass is complete -- valuesDisbursed = 0; -- } -+ /** Reset for another pass over the same value set. */ -+ public void resetForSecondPass() { -+ assert(phase() == DISBURSE_PHASE); -+ assert(valuesDisbursed == length()); // 1st pass is complete -+ valuesDisbursed = 0; -+ } - } - - class ByteBand extends Band { -- private ByteArrayOutputStream bytes; // input buffer -- private ByteArrayOutputStream bytesForDump; -- private InputStream in; -+ private ByteArrayOutputStream bytes; // input buffer -+ private ByteArrayOutputStream bytesForDump; -+ private InputStream in; - -- public ByteBand(String name) { -- super(name, BYTE1); -- } -+ public ByteBand(String name) { -+ super(name, BYTE1); -+ } - -- public int capacity() { -- return bytes == null ? -1 : Integer.MAX_VALUE; -- } -- protected void setCapacity(int cap) { -- assert(bytes == null); // do this just once -- bytes = new ByteArrayOutputStream(cap); -- } -- public void destroy() { -- lengthForDebug = length(); -- bytes = null; -- } -+ public int capacity() { -+ return bytes == null ? -1 : Integer.MAX_VALUE; -+ } -+ protected void setCapacity(int cap) { -+ assert(bytes == null); // do this just once -+ bytes = new ByteArrayOutputStream(cap); -+ } -+ public void destroy() { -+ lengthForDebug = length(); -+ bytes = null; -+ } - -- public int length() { -- return bytes == null ? -1 : bytes.size(); -- } -- public void reset() { -- bytes.reset(); -- } -- protected int valuesRemainingForDebug() { -- return (bytes == null) ? -1 : ((ByteArrayInputStream)in).available(); -- } -+ public int length() { -+ return bytes == null ? -1 : bytes.size(); -+ } -+ public void reset() { -+ bytes.reset(); -+ } -+ protected int valuesRemainingForDebug() { -+ return (bytes == null) ? -1 : ((ByteArrayInputStream)in).available(); -+ } - -- protected void chooseBandCodings() throws IOException { -- // No-op. -- assert(decodeEscapeValue(regularCoding.min(), regularCoding) < 0); -- assert(decodeEscapeValue(regularCoding.max(), regularCoding) < 0); -- } -+ protected void chooseBandCodings() throws IOException { -+ // No-op. -+ assert(decodeEscapeValue(regularCoding.min(), regularCoding) < 0); -+ assert(decodeEscapeValue(regularCoding.max(), regularCoding) < 0); -+ } - -- protected long computeOutputSize() { -- // do not cache -- return bytes.size(); -- } -+ protected long computeOutputSize() { -+ // do not cache -+ return bytes.size(); -+ } - -- public void writeDataTo(OutputStream out) throws IOException { -- if (length() == 0) return; -- bytes.writeTo(out); -- if (optDumpBands) dumpBand(); -- destroy(); // done with the bits! -- } -+ public void writeDataTo(OutputStream out) throws IOException { -+ if (length() == 0) return; -+ bytes.writeTo(out); -+ if (optDumpBands) dumpBand(); -+ destroy(); // done with the bits! -+ } - -- private void dumpBand() throws IOException { -- assert(optDumpBands); -- OutputStream ds = getDumpStream(this, ".bnd"); -- if (bytesForDump != null) -- bytesForDump.writeTo(ds); -- else -- bytes.writeTo(ds); -- ds.close(); -- } -+ private void dumpBand() throws IOException { -+ assert(optDumpBands); -+ OutputStream ds = getDumpStream(this, ".bnd"); -+ if (bytesForDump != null) -+ bytesForDump.writeTo(ds); -+ else -+ bytes.writeTo(ds); -+ ds.close(); -+ } - -- public void readDataFrom(InputStream in) throws IOException { -- int vex = valuesExpected(); -- if (vex == 0) return; -- if (verbose > 1) { -- lengthForDebug = vex; -- Utils.log.fine("Reading band "+this); -- lengthForDebug = -1; -- } -- byte[] buf = new byte[Math.min(vex, 1<<14)]; -- while (vex > 0) { -- int nr = in.read(buf, 0, Math.min(vex, buf.length)); -- if (nr < 0) throw new EOFException(); -- bytes.write(buf, 0, nr); -- vex -= nr; -- } -- if (optDumpBands) dumpBand(); -- } -+ public void readDataFrom(InputStream in) throws IOException { -+ int vex = valuesExpected(); -+ if (vex == 0) return; -+ if (verbose > 1) { -+ lengthForDebug = vex; -+ Utils.log.fine("Reading band "+this); -+ lengthForDebug = -1; -+ } -+ byte[] buf = new byte[Math.min(vex, 1<<14)]; -+ while (vex > 0) { -+ int nr = in.read(buf, 0, Math.min(vex, buf.length)); -+ if (nr < 0) throw new EOFException(); -+ bytes.write(buf, 0, nr); -+ vex -= nr; -+ } -+ if (optDumpBands) dumpBand(); -+ } - -- public void readyToDisburse() { -- in = new ByteArrayInputStream(bytes.toByteArray()); -- super.readyToDisburse(); -- } -+ public void readyToDisburse() { -+ in = new ByteArrayInputStream(bytes.toByteArray()); -+ super.readyToDisburse(); -+ } - -- public void doneDisbursing() { -- super.doneDisbursing(); -- if (optDumpBands -- && bytesForDump != null && bytesForDump.size() > 0) { -- try { -- dumpBand(); -- } catch (IOException ee) { -- throw new RuntimeException(ee); -- } -- } -- in = null; // GC -- bytes = null; // GC -- bytesForDump = null; // GC -- } -+ public void doneDisbursing() { -+ super.doneDisbursing(); -+ if (optDumpBands -+ && bytesForDump != null && bytesForDump.size() > 0) { -+ try { -+ dumpBand(); -+ } catch (IOException ee) { -+ throw new RuntimeException(ee); -+ } -+ } -+ in = null; // GC -+ bytes = null; // GC -+ bytesForDump = null; // GC -+ } - -- // alternative to readFrom: -- public void setInputStreamFrom(InputStream in) throws IOException { -- assert(bytes == null); -- assert(assertReadyToReadFrom(this, in)); -- setPhase(READ_PHASE); -- this.in = in; -- if (optDumpBands) { -- // Tap the stream. -- bytesForDump = new ByteArrayOutputStream(); -- this.in = new FilterInputStream(in) { -- public int read() throws IOException { -- int ch = in.read(); -- if (ch >= 0) bytesForDump.write(ch); -- return ch; -- } -- public int read(byte b[], int off, int len) throws IOException { -- int nr = in.read(b, off, len); -- if (nr >= 0) bytesForDump.write(b, off, nr); -- return nr; -- } -- }; -- } -- super.readyToDisburse(); -- } -+ // alternative to readFrom: -+ public void setInputStreamFrom(InputStream in) throws IOException { -+ assert(bytes == null); -+ assert(assertReadyToReadFrom(this, in)); -+ setPhase(READ_PHASE); -+ this.in = in; -+ if (optDumpBands) { -+ // Tap the stream. -+ bytesForDump = new ByteArrayOutputStream(); -+ this.in = new FilterInputStream(in) { -+ public int read() throws IOException { -+ int ch = in.read(); -+ if (ch >= 0) bytesForDump.write(ch); -+ return ch; -+ } -+ public int read(byte b[], int off, int len) throws IOException { -+ int nr = in.read(b, off, len); -+ if (nr >= 0) bytesForDump.write(b, off, nr); -+ return nr; -+ } -+ }; -+ } -+ super.readyToDisburse(); -+ } - -- public OutputStream collectorStream() { -- assert(phase() == COLLECT_PHASE); -- assert(bytes != null); -- return bytes; -- } -+ public OutputStream collectorStream() { -+ assert(phase() == COLLECT_PHASE); -+ assert(bytes != null); -+ return bytes; -+ } - -- public InputStream getInputStream() { -- assert(phase() == DISBURSE_PHASE); -- assert(in != null); -- return in; -- } -- public int getByte() throws IOException { -- int b = getInputStream().read(); -- if (b < 0) throw new EOFException(); -- return b; -- } -- public void putByte(int b) throws IOException { -- assert(b == (b & 0xFF)); -- collectorStream().write(b); -- } -- public String toString() { -- return "byte "+super.toString(); -- } -+ public InputStream getInputStream() { -+ assert(phase() == DISBURSE_PHASE); -+ assert(in != null); -+ return in; -+ } -+ public int getByte() throws IOException { -+ int b = getInputStream().read(); -+ if (b < 0) throw new EOFException(); -+ return b; -+ } -+ public void putByte(int b) throws IOException { -+ assert(b == (b & 0xFF)); -+ collectorStream().write(b); -+ } -+ public String toString() { -+ return "byte "+super.toString(); -+ } - } - - class IntBand extends ValueBand { -- // The usual coding for bands is 7bit/5byte/delta. -- public IntBand(String name, Coding regularCoding) { -- super(name, regularCoding); -- } -+ // The usual coding for bands is 7bit/5byte/delta. -+ public IntBand(String name, Coding regularCoding) { -+ super(name, regularCoding); -+ } - -- public void putInt(int x) { -- assert(phase() == COLLECT_PHASE); -- addValue(x); -- } -+ public void putInt(int x) { -+ assert(phase() == COLLECT_PHASE); -+ addValue(x); -+ } - -- public int getInt() { -- return getValue(); -- } -- /** Return the sum of all values in this band. */ -- public int getIntTotal() { -- assert(phase() == DISBURSE_PHASE); -- // assert that this is the whole pass; no other reads allowed -- assert(valuesRemainingForDebug() == length()); -- int total = 0; -- for (int k = length(); k > 0; k--) { -- total += getInt(); -- } -- resetForSecondPass(); -- return total; -- } -- /** Return the occurrence count of a specific value in this band. */ -- public int getIntCount(int value) { -- assert(phase() == DISBURSE_PHASE); -- // assert that this is the whole pass; no other reads allowed -- assert(valuesRemainingForDebug() == length()); -- int total = 0; -- for (int k = length(); k > 0; k--) { -- if (getInt() == value) { -- total += 1; -- } -- } -- resetForSecondPass(); -- return total; -- } -+ public int getInt() { -+ return getValue(); -+ } -+ /** Return the sum of all values in this band. */ -+ public int getIntTotal() { -+ assert(phase() == DISBURSE_PHASE); -+ // assert that this is the whole pass; no other reads allowed -+ assert(valuesRemainingForDebug() == length()); -+ int total = 0; -+ for (int k = length(); k > 0; k--) { -+ total += getInt(); -+ } -+ resetForSecondPass(); -+ return total; -+ } -+ /** Return the occurrence count of a specific value in this band. */ -+ public int getIntCount(int value) { -+ assert(phase() == DISBURSE_PHASE); -+ // assert that this is the whole pass; no other reads allowed -+ assert(valuesRemainingForDebug() == length()); -+ int total = 0; -+ for (int k = length(); k > 0; k--) { -+ if (getInt() == value) { -+ total += 1; -+ } -+ } -+ resetForSecondPass(); -+ return total; -+ } - } - - static int getIntTotal(int[] values) { -- int total = 0; -- for (int i = 0; i < values.length; i++) { -- total += values[i]; -- } -- return total; -+ int total = 0; -+ for (int i = 0; i < values.length; i++) { -+ total += values[i]; -+ } -+ return total; - } - - class CPRefBand extends ValueBand { -- Index index; -- boolean nullOK; -+ Index index; -+ boolean nullOK; - -- public CPRefBand(String name, Coding regularCoding, byte cpTag, boolean nullOK) { -- super(name, regularCoding); -- this.nullOK = nullOK; -- if (cpTag != CONSTANT_None) -- setBandIndex(this, cpTag); -- } -- public CPRefBand(String name, Coding regularCoding, byte cpTag) { -- this(name, regularCoding, cpTag, false); -- } -- public CPRefBand(String name, Coding regularCoding, Object undef) { -- this(name, regularCoding, CONSTANT_None, false); -- } -+ public CPRefBand(String name, Coding regularCoding, byte cpTag, boolean nullOK) { -+ super(name, regularCoding); -+ this.nullOK = nullOK; -+ if (cpTag != CONSTANT_None) -+ setBandIndex(this, cpTag); -+ } -+ public CPRefBand(String name, Coding regularCoding, byte cpTag) { -+ this(name, regularCoding, cpTag, false); -+ } -+ public CPRefBand(String name, Coding regularCoding, Object undef) { -+ this(name, regularCoding, CONSTANT_None, false); -+ } - -- public void setIndex(Index index) { -- this.index = index; -- } -+ public void setIndex(Index index) { -+ this.index = index; -+ } - -- protected void readDataFrom(InputStream in) throws IOException { -- super.readDataFrom(in); -- assert(assertValidCPRefs(this)); -- } -+ protected void readDataFrom(InputStream in) throws IOException { -+ super.readDataFrom(in); -+ assert(assertValidCPRefs(this)); -+ } - -- /** Write a constant pool reference. */ -- public void putRef(Entry e) { -- assert(index != null); -- addValue(encodeRefOrNull(e, index)); -- } -- public void putRef(Entry e, Index index) { -- assert(this.index == null); -- addValue(encodeRefOrNull(e, index)); -- } -- public void putRef(Entry e, byte cptag) { -- putRef(e, getCPIndex(cptag)); -- } -+ /** Write a constant pool reference. */ -+ public void putRef(Entry e) { -+ addValue(encodeRefOrNull(e, index)); -+ } -+ public void putRef(Entry e, Index index) { -+ assert(this.index == null); -+ addValue(encodeRefOrNull(e, index)); -+ } -+ public void putRef(Entry e, byte cptag) { -+ putRef(e, getCPIndex(cptag)); -+ } - -- public Entry getRef() { -- if (index == null) Utils.log.warning("No index for "+this); -- assert(index != null); -- return decodeRefOrNull(getValue(), index); -- } -- public Entry getRef(Index index) { -- assert(this.index == null); -- return decodeRefOrNull(getValue(), index); -- } -- public Entry getRef(byte cptag) { -- return getRef(getCPIndex(cptag)); -- } -+ public Entry getRef() { -+ if (index == null) Utils.log.warning("No index for "+this); -+ assert(index != null); -+ return decodeRefOrNull(getValue(), index); -+ } -+ public Entry getRef(Index index) { -+ assert(this.index == null); -+ return decodeRefOrNull(getValue(), index); -+ } -+ public Entry getRef(byte cptag) { -+ return getRef(getCPIndex(cptag)); -+ } - -- private int encodeRefOrNull(Entry e, Index index) { -- int nonNullCode; // NNC is the coding which assumes nulls are rare -- if (e == null) { -- nonNullCode = -1; // negative values are rare -- } else { -- nonNullCode = encodeRef(e, index); -- } -- // If nulls are expected, increment, to make -1 code turn to 0. -- return (nullOK ? 1 : 0) + nonNullCode; -- } -- private Entry decodeRefOrNull(int code, Index index) { -- // Inverse to encodeRefOrNull... -- int nonNullCode = code - (nullOK ? 1 : 0); -- if (nonNullCode == -1) { -- return null; -- } else { -- return decodeRef(nonNullCode, index); -- } -- } -+ private int encodeRefOrNull(Entry e, Index index) { -+ int nonNullCode; // NNC is the coding which assumes nulls are rare -+ if (e == null) { -+ nonNullCode = -1; // negative values are rare -+ } else { -+ nonNullCode = encodeRef(e, index); -+ } -+ // If nulls are expected, increment, to make -1 code turn to 0. -+ return (nullOK ? 1 : 0) + nonNullCode; -+ } -+ private Entry decodeRefOrNull(int code, Index index) { -+ // Inverse to encodeRefOrNull... -+ int nonNullCode = code - (nullOK ? 1 : 0); -+ if (nonNullCode == -1) { -+ return null; -+ } else { -+ return decodeRef(nonNullCode, index); -+ } -+ } - } - - // Bootstrap support for CPRefBands. These are needed to record -@@ -1039,51 +1037,53 @@ class BandStructure implements Constants - - - int encodeRef(Entry e, Index ix) { -- int coding = ix.indexOf(e); -- if (verbose > 2) -- Utils.log.fine("putRef "+coding+" => "+e); -- return coding; -+ if (ix == null) -+ throw new RuntimeException("null index for " + e.stringValue()); -+ int coding = ix.indexOf(e); -+ if (verbose > 2) -+ Utils.log.fine("putRef "+coding+" => "+e); -+ return coding; - } - - Entry decodeRef(int n, Index ix) { -- if (n < 0 || n >= ix.size()) -- Utils.log.warning("decoding bad ref "+n+" in "+ix); -- Entry e = ix.getEntry(n); -- if (verbose > 2) -- Utils.log.fine("getRef "+n+" => "+e); -- return e; -+ if (n < 0 || n >= ix.size()) -+ Utils.log.warning("decoding bad ref "+n+" in "+ix); -+ Entry e = ix.getEntry(n); -+ if (verbose > 2) -+ Utils.log.fine("getRef "+n+" => "+e); -+ return e; - } - - private CodingChooser codingChooser; - protected CodingChooser getCodingChooser() { -- if (codingChooser == null) { -- codingChooser = new CodingChooser(effort, basicCodings); -- if (codingChooser.stress != null -- && this instanceof PackageWriter) { -- // Twist the random state based on my first file. -- // This sends each segment off in a different direction. -- List classes = ((PackageWriter)this).pkg.classes; -- if (!classes.isEmpty()) { -- Package.Class cls = (Package.Class) classes.get(0); -- codingChooser.addStressSeed(cls.getName().hashCode()); -- } -- } -- } -- return codingChooser; -+ if (codingChooser == null) { -+ codingChooser = new CodingChooser(effort, basicCodings); -+ if (codingChooser.stress != null -+ && this instanceof PackageWriter) { -+ // Twist the random state based on my first file. -+ // This sends each segment off in a different direction. -+ List classes = ((PackageWriter)this).pkg.classes; -+ if (!classes.isEmpty()) { -+ Package.Class cls = (Package.Class) classes.get(0); -+ codingChooser.addStressSeed(cls.getName().hashCode()); -+ } -+ } -+ } -+ return codingChooser; - } - - public CodingMethod chooseCoding(int[] values, int start, int end, -- Coding regular, String bandName, -- int[] sizes) { -- assert(optVaryCodings); -- if (effort <= MIN_EFFORT) { -- return regular; -- } -- CodingChooser cc = getCodingChooser(); -- if (verbose > 1 || cc.verbose > 1) { -- Utils.log.fine("--- chooseCoding "+bandName); -- } -- return cc.choose(values, start, end, regular, sizes); -+ Coding regular, String bandName, -+ int[] sizes) { -+ assert(optVaryCodings); -+ if (effort <= MIN_EFFORT) { -+ return regular; -+ } -+ CodingChooser cc = getCodingChooser(); -+ if (verbose > 1 || cc.verbose > 1) { -+ Utils.log.fine("--- chooseCoding "+bandName); -+ } -+ return cc.choose(values, start, end, regular, sizes); - } - - static final byte[] defaultMetaCoding = { _meta_default }; -@@ -1108,201 +1108,201 @@ class BandStructure implements Constants - // Result is in [0..255] if XB was successfully extracted, else -1. - // See section "Coding Specifier Meta-Encoding" in the JSR 200 spec. - protected static int decodeEscapeValue(int X, Coding regularCoding) { -- // The first value in a band is always coded with the default coding D. -- // If this first value X is an escape value, it actually represents the -- // first (and perhaps only) byte of a meta-coding. -- // Result is in [0..255] if XB was successfully extracted, else -1. -- if (regularCoding.B() == 1 || regularCoding.L() == 0) -- return -1; // degenerate regular coding (BYTE1) -- if (regularCoding.S() != 0) { -- if (-256 <= X && X <= -1 && regularCoding.min() <= -256) { -- int XB = -1-X; -- assert(XB >= 0 && XB < 256); -- return XB; -- } -- } else { -- int L = regularCoding.L(); -- if (L <= X && X <= L+255 && regularCoding.max() >= L+255) { -- int XB = X-L; -- assert(XB >= 0 && XB < 256); -- return XB; -- } -- } -- return -1; // negative value for failure -+ // The first value in a band is always coded with the default coding D. -+ // If this first value X is an escape value, it actually represents the -+ // first (and perhaps only) byte of a meta-coding. -+ // Result is in [0..255] if XB was successfully extracted, else -1. -+ if (regularCoding.B() == 1 || regularCoding.L() == 0) -+ return -1; // degenerate regular coding (BYTE1) -+ if (regularCoding.S() != 0) { -+ if (-256 <= X && X <= -1 && regularCoding.min() <= -256) { -+ int XB = -1-X; -+ assert(XB >= 0 && XB < 256); -+ return XB; -+ } -+ } else { -+ int L = regularCoding.L(); -+ if (L <= X && X <= L+255 && regularCoding.max() >= L+255) { -+ int XB = X-L; -+ assert(XB >= 0 && XB < 256); -+ return XB; -+ } -+ } -+ return -1; // negative value for failure - } - // Inverse to decodeEscapeValue(). - protected static int encodeEscapeValue(int XB, Coding regularCoding) { -- assert(XB >= 0 && XB < 256); -- assert(regularCoding.B() > 1 && regularCoding.L() > 0); -- int X; -- if (regularCoding.S() != 0) { -- assert(regularCoding.min() <= -256); -- X = -1-XB; -- } else { -- int L = regularCoding.L(); -- assert(regularCoding.max() >= L+255); -- X = XB+L; -- } -- assert(decodeEscapeValue(X, regularCoding) == XB) -- : (regularCoding+" XB="+XB+" X="+X); -- return X; -+ assert(XB >= 0 && XB < 256); -+ assert(regularCoding.B() > 1 && regularCoding.L() > 0); -+ int X; -+ if (regularCoding.S() != 0) { -+ assert(regularCoding.min() <= -256); -+ X = -1-XB; -+ } else { -+ int L = regularCoding.L(); -+ assert(regularCoding.max() >= L+255); -+ X = XB+L; -+ } -+ assert(decodeEscapeValue(X, regularCoding) == XB) -+ : (regularCoding+" XB="+XB+" X="+X); -+ return X; - } - - static { -- boolean checkXB = false; -- assert(checkXB = true); -- if (checkXB) { -- for (int i = 0; i < basicCodings.length; i++) { -- Coding D = basicCodings[i]; -- if (D == null) continue; -- if (D.B() == 1) continue; -- if (D.L() == 0) continue; -- for (int XB = 0; XB <= 255; XB++) { -- // The following exercises decodeEscapeValue also: -- encodeEscapeValue(XB, D); -- } -- } -- } -+ boolean checkXB = false; -+ assert(checkXB = true); -+ if (checkXB) { -+ for (int i = 0; i < basicCodings.length; i++) { -+ Coding D = basicCodings[i]; -+ if (D == null) continue; -+ if (D.B() == 1) continue; -+ if (D.L() == 0) continue; -+ for (int XB = 0; XB <= 255; XB++) { -+ // The following exercises decodeEscapeValue also: -+ encodeEscapeValue(XB, D); -+ } -+ } -+ } - } - - class MultiBand extends Band { -- MultiBand(String name, Coding regularCoding) { -- super(name, regularCoding); -- } -+ MultiBand(String name, Coding regularCoding) { -+ super(name, regularCoding); -+ } - -- public Band init() { -- super.init(); -- // This is all just to keep the asserts happy: -- setCapacity(0); -- if (phase() == EXPECT_PHASE) { -- // Fast forward: -- setPhase(READ_PHASE); -- setPhase(DISBURSE_PHASE); -- } -- return this; -- } -+ public Band init() { -+ super.init(); -+ // This is all just to keep the asserts happy: -+ setCapacity(0); -+ if (phase() == EXPECT_PHASE) { -+ // Fast forward: -+ setPhase(READ_PHASE); -+ setPhase(DISBURSE_PHASE); -+ } -+ return this; -+ } - -- Band[] bands = new Band[10]; -- int bandCount = 0; -+ Band[] bands = new Band[10]; -+ int bandCount = 0; - -- int size() { -- return bandCount; -- } -- Band get(int i) { -- assert(i < bandCount); -- return bands[i]; -- } -- Band[] toArray() { -- return (Band[]) realloc(bands, bandCount); -- } -+ int size() { -+ return bandCount; -+ } -+ Band get(int i) { -+ assert(i < bandCount); -+ return bands[i]; -+ } -+ Band[] toArray() { -+ return (Band[]) realloc(bands, bandCount); -+ } - -- void add(Band b) { -- assert(bandCount == 0 || notePrevForAssert(b, bands[bandCount-1])); -- if (bandCount == bands.length) { -- bands = (Band[]) realloc(bands); -- } -- bands[bandCount++] = b; -- } -+ void add(Band b) { -+ assert(bandCount == 0 || notePrevForAssert(b, bands[bandCount-1])); -+ if (bandCount == bands.length) { -+ bands = (Band[]) realloc(bands); -+ } -+ bands[bandCount++] = b; -+ } - -- ByteBand newByteBand(String name) { -- ByteBand b = new ByteBand(name); -- b.init(); add(b); -- return b; -- } -- IntBand newIntBand(String name) { -- IntBand b = new IntBand(name, regularCoding); -- b.init(); add(b); -- return b; -- } -- IntBand newIntBand(String name, Coding regularCoding) { -- IntBand b = new IntBand(name, regularCoding); -- b.init(); add(b); -- return b; -- } -- MultiBand newMultiBand(String name, Coding regularCoding) { -- MultiBand b = new MultiBand(name, regularCoding); -- b.init(); add(b); -- return b; -- } -- CPRefBand newCPRefBand(String name, byte cpTag) { -- CPRefBand b = new CPRefBand(name, regularCoding, cpTag); -- b.init(); add(b); -- return b; -- } -- CPRefBand newCPRefBand(String name, Coding regularCoding, -- byte cpTag) { -- CPRefBand b = new CPRefBand(name, regularCoding, cpTag); -- b.init(); add(b); -- return b; -- } -- CPRefBand newCPRefBand(String name, Coding regularCoding, -- byte cpTag, boolean nullOK) { -- CPRefBand b = new CPRefBand(name, regularCoding, cpTag, nullOK); -- b.init(); add(b); -- return b; -- } -+ ByteBand newByteBand(String name) { -+ ByteBand b = new ByteBand(name); -+ b.init(); add(b); -+ return b; -+ } -+ IntBand newIntBand(String name) { -+ IntBand b = new IntBand(name, regularCoding); -+ b.init(); add(b); -+ return b; -+ } -+ IntBand newIntBand(String name, Coding regularCoding) { -+ IntBand b = new IntBand(name, regularCoding); -+ b.init(); add(b); -+ return b; -+ } -+ MultiBand newMultiBand(String name, Coding regularCoding) { -+ MultiBand b = new MultiBand(name, regularCoding); -+ b.init(); add(b); -+ return b; -+ } -+ CPRefBand newCPRefBand(String name, byte cpTag) { -+ CPRefBand b = new CPRefBand(name, regularCoding, cpTag); -+ b.init(); add(b); -+ return b; -+ } -+ CPRefBand newCPRefBand(String name, Coding regularCoding, -+ byte cpTag) { -+ CPRefBand b = new CPRefBand(name, regularCoding, cpTag); -+ b.init(); add(b); -+ return b; -+ } -+ CPRefBand newCPRefBand(String name, Coding regularCoding, -+ byte cpTag, boolean nullOK) { -+ CPRefBand b = new CPRefBand(name, regularCoding, cpTag, nullOK); -+ b.init(); add(b); -+ return b; -+ } - -- int bandCount() { return bandCount; } -+ int bandCount() { return bandCount; } - -- private int cap = -1; -- public int capacity() { return cap; } -- public void setCapacity(int cap) { this.cap = cap; } -+ private int cap = -1; -+ public int capacity() { return cap; } -+ public void setCapacity(int cap) { this.cap = cap; } - -- public int length() { return 0; } -- public int valuesRemainingForDebug() { return 0; } -+ public int length() { return 0; } -+ public int valuesRemainingForDebug() { return 0; } - -- protected void chooseBandCodings() throws IOException { -- // coding decision pass -- for (int i = 0; i < bandCount; i++) { -- Band b = bands[i]; -- b.chooseBandCodings(); -- } -- } -+ protected void chooseBandCodings() throws IOException { -+ // coding decision pass -+ for (int i = 0; i < bandCount; i++) { -+ Band b = bands[i]; -+ b.chooseBandCodings(); -+ } -+ } - -- protected long computeOutputSize() { -- // coding decision pass -- long sum = 0; -- for (int i = 0; i < bandCount; i++) { -- Band b = bands[i]; -- long bsize = b.outputSize(); -- assert(bsize >= 0) : b; -- sum += bsize; -- } -- // do not cache -- return sum; -- } -+ protected long computeOutputSize() { -+ // coding decision pass -+ long sum = 0; -+ for (int i = 0; i < bandCount; i++) { -+ Band b = bands[i]; -+ long bsize = b.outputSize(); -+ assert(bsize >= 0) : b; -+ sum += bsize; -+ } -+ // do not cache -+ return sum; -+ } - -- protected void writeDataTo(OutputStream out) throws IOException { -- long preCount = 0; -- if (outputCounter != null) preCount = outputCounter.getCount(); -- for (int i = 0; i < bandCount; i++) { -- Band b = bands[i]; -- b.writeTo(out); -- if (outputCounter != null) { -- long postCount = outputCounter.getCount(); -- long len = postCount - preCount; -- preCount = postCount; -- if ((verbose > 0 && len > 0) || verbose > 1) { -- Utils.log.info(" ...wrote "+len+" bytes from "+b); -- } -- } -- } -- } -+ protected void writeDataTo(OutputStream out) throws IOException { -+ long preCount = 0; -+ if (outputCounter != null) preCount = outputCounter.getCount(); -+ for (int i = 0; i < bandCount; i++) { -+ Band b = bands[i]; -+ b.writeTo(out); -+ if (outputCounter != null) { -+ long postCount = outputCounter.getCount(); -+ long len = postCount - preCount; -+ preCount = postCount; -+ if ((verbose > 0 && len > 0) || verbose > 1) { -+ Utils.log.info(" ...wrote "+len+" bytes from "+b); -+ } -+ } -+ } -+ } - -- protected void readDataFrom(InputStream in) throws IOException { -- assert(false); // not called? -- for (int i = 0; i < bandCount; i++) { -- Band b = bands[i]; -- b.readFrom(in); -- if ((verbose > 0 && b.length() > 0) || verbose > 1) { -- Utils.log.info(" ...read "+b); -- } -- } -- } -+ protected void readDataFrom(InputStream in) throws IOException { -+ assert(false); // not called? -+ for (int i = 0; i < bandCount; i++) { -+ Band b = bands[i]; -+ b.readFrom(in); -+ if ((verbose > 0 && b.length() > 0) || verbose > 1) { -+ Utils.log.info(" ...read "+b); -+ } -+ } -+ } - -- public String toString() { -- return "{"+bandCount()+" bands: "+super.toString()+"}"; -- } -+ public String toString() { -+ return "{"+bandCount()+" bands: "+super.toString()+"}"; -+ } - } - - /** -@@ -1310,42 +1310,42 @@ class BandStructure implements Constants - */ - private static - class ByteCounter extends FilterOutputStream { -- // (should go public under the name CountingOutputStream?) -+ // (should go public under the name CountingOutputStream?) - -- private long count; -+ private long count; - -- public ByteCounter(OutputStream out) { -- super(out); -- } -+ public ByteCounter(OutputStream out) { -+ super(out); -+ } - -- public long getCount() { return count; } -- public void setCount(long c) { count = c; } -+ public long getCount() { return count; } -+ public void setCount(long c) { count = c; } - -- public void write(int b) throws IOException { -- count++; -- if (out != null) out.write(b); -- } -- public void write(byte b[], int off, int len) throws IOException { -- count += len; -- if (out != null) out.write(b, off, len); -- } -- public String toString() { -- return String.valueOf(getCount()); -- } -+ public void write(int b) throws IOException { -+ count++; -+ if (out != null) out.write(b); -+ } -+ public void write(byte b[], int off, int len) throws IOException { -+ count += len; -+ if (out != null) out.write(b, off, len); -+ } -+ public String toString() { -+ return String.valueOf(getCount()); -+ } - } - ByteCounter outputCounter; - - void writeAllBandsTo(OutputStream out) throws IOException { -- // Wrap a byte-counter around the output stream. -- outputCounter = new ByteCounter(out); -- out = outputCounter; -- all_bands.writeTo(out); -- if (verbose > 0) { -- long nbytes = outputCounter.getCount(); -- Utils.log.info("Wrote total of "+nbytes+" bytes."); -- assert(nbytes == archiveSize0+archiveSize1); -- } -- outputCounter = null; -+ // Wrap a byte-counter around the output stream. -+ outputCounter = new ByteCounter(out); -+ out = outputCounter; -+ all_bands.writeTo(out); -+ if (verbose > 0) { -+ long nbytes = outputCounter.getCount(); -+ Utils.log.info("Wrote total of "+nbytes+" bytes."); -+ assert(nbytes == archiveSize0+archiveSize1); -+ } -+ outputCounter = null; - } - - // random AO_XXX bits, decoded from the archive header -@@ -1366,7 +1366,7 @@ class BandStructure implements Constants - static final int AH_SPECIAL_FORMAT_LEN = 2; // layouts/band-headers - static final int AH_CP_NUMBER_LEN = 4; // int/float/long/double - static final int AH_LENGTH_MIN = AH_LENGTH -- -(AH_SPECIAL_FORMAT_LEN+AH_FILE_HEADER_LEN+AH_CP_NUMBER_LEN); -+ -(AH_SPECIAL_FORMAT_LEN+AH_FILE_HEADER_LEN+AH_CP_NUMBER_LEN); - - // Common structure of attribute band groups: - static final int AB_FLAGS_HI = 0; -@@ -1376,22 +1376,22 @@ class BandStructure implements Constants - static final int AB_ATTR_CALLS = 4; - - static IntBand getAttrBand(MultiBand xxx_attr_bands, int which) { -- IntBand b = (IntBand) xxx_attr_bands.get(which); -- switch (which) { -- case AB_FLAGS_HI: -- assert(b.name().endsWith("_flags_hi")); break; -- case AB_FLAGS_LO: -- assert(b.name().endsWith("_flags_lo")); break; -- case AB_ATTR_COUNT: -- assert(b.name().endsWith("_attr_count")); break; -- case AB_ATTR_INDEXES: -- assert(b.name().endsWith("_attr_indexes")); break; -- case AB_ATTR_CALLS: -- assert(b.name().endsWith("_attr_calls")); break; -- default: -- assert(false); break; -- } -- return b; -+ IntBand b = (IntBand) xxx_attr_bands.get(which); -+ switch (which) { -+ case AB_FLAGS_HI: -+ assert(b.name().endsWith("_flags_hi")); break; -+ case AB_FLAGS_LO: -+ assert(b.name().endsWith("_flags_lo")); break; -+ case AB_ATTR_COUNT: -+ assert(b.name().endsWith("_attr_count")); break; -+ case AB_ATTR_INDEXES: -+ assert(b.name().endsWith("_attr_indexes")); break; -+ case AB_ATTR_CALLS: -+ assert(b.name().endsWith("_attr_calls")); break; -+ default: -+ assert(false); break; -+ } -+ return b; - } - - static private final boolean NULL_IS_OK = true; -@@ -1602,55 +1602,55 @@ class BandStructure implements Constants - - /** Given CP indexes, distribute tag-specific indexes to bands. */ - protected void setBandIndexes() { -- // Handle prior calls to setBandIndex: -- for (Iterator i = needPredefIndex.iterator(); i.hasNext(); ) { -- Object[] need = (Object[]) i.next(); -- CPRefBand b = (CPRefBand) need[0]; -- Byte which = (Byte) need[1]; -- b.setIndex(getCPIndex(which.byteValue())); -- } -- needPredefIndex = null; // no more predefs -+ // Handle prior calls to setBandIndex: -+ for (Iterator i = needPredefIndex.iterator(); i.hasNext(); ) { -+ Object[] need = (Object[]) i.next(); -+ CPRefBand b = (CPRefBand) need[0]; -+ Byte which = (Byte) need[1]; -+ b.setIndex(getCPIndex(which.byteValue())); -+ } -+ needPredefIndex = null; // no more predefs - -- if (verbose > 3) { -- printCDecl(all_bands); -- } -+ if (verbose > 3) { -+ printCDecl(all_bands); -+ } - } - - protected void setBandIndex(CPRefBand b, byte which) { -- Object[] need = { b, new Byte(which) }; -- if (which == CONSTANT_Literal) { -- // I.e., attribute layouts KQ (no null) or KQN (null ok). -- allKQBands.add(b); -- } else if (needPredefIndex != null) { -- needPredefIndex.add(need); -- } else { -- // Not in predefinition mode; getCPIndex now works. -- b.setIndex(getCPIndex(which)); -- } -+ Object[] need = { b, new Byte(which) }; -+ if (which == CONSTANT_Literal) { -+ // I.e., attribute layouts KQ (no null) or KQN (null ok). -+ allKQBands.add(b); -+ } else if (needPredefIndex != null) { -+ needPredefIndex.add(need); -+ } else { -+ // Not in predefinition mode; getCPIndex now works. -+ b.setIndex(getCPIndex(which)); -+ } - } - - protected void setConstantValueIndex(Class.Field f) { -- Index ix = null; -- if (f != null) { -- byte tag = f.getLiteralTag(); -- ix = getCPIndex(tag); -- if (verbose > 2) -- Utils.log.fine("setConstantValueIndex "+f+" "+ConstantPool.tagName(tag)+" => "+ix); -- assert(ix != null); -- } -- // Typically, allKQBands is the singleton of field_ConstantValue_KQ. -- for (Iterator i = allKQBands.iterator(); i.hasNext(); ) { -- CPRefBand xxx_KQ = (CPRefBand) i.next(); -- xxx_KQ.setIndex(ix); -- } -+ Index ix = null; -+ if (f != null) { -+ byte tag = f.getLiteralTag(); -+ ix = getCPIndex(tag); -+ if (verbose > 2) -+ Utils.log.fine("setConstantValueIndex "+f+" "+ConstantPool.tagName(tag)+" => "+ix); -+ assert(ix != null); -+ } -+ // Typically, allKQBands is the singleton of field_ConstantValue_KQ. -+ for (Iterator i = allKQBands.iterator(); i.hasNext(); ) { -+ CPRefBand xxx_KQ = (CPRefBand) i.next(); -+ xxx_KQ.setIndex(ix); -+ } - } - - // Table of bands which contain metadata. - protected MultiBand[] metadataBands = new MultiBand[ATTR_CONTEXT_LIMIT]; - { -- metadataBands[ATTR_CONTEXT_CLASS] = class_metadata_bands; -- metadataBands[ATTR_CONTEXT_FIELD] = field_metadata_bands; -- metadataBands[ATTR_CONTEXT_METHOD] = method_metadata_bands; -+ metadataBands[ATTR_CONTEXT_CLASS] = class_metadata_bands; -+ metadataBands[ATTR_CONTEXT_FIELD] = field_metadata_bands; -+ metadataBands[ATTR_CONTEXT_METHOD] = method_metadata_bands; - } - - // Attribute layouts. -@@ -1686,660 +1686,660 @@ class BandStructure implements Constants - // Mapping from attribute index (<32 are flag bits) to attributes. - protected ArrayList[] attrDefs = new ArrayList[ATTR_CONTEXT_LIMIT]; - { -- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -- assert(attrIndexLimit[i] == 0); -- attrIndexLimit[i] = 32; // just for the sake of predefs. -- attrDefs[i] = new ArrayList(Collections.nCopies(attrIndexLimit[i], null)); -- } -+ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -+ assert(attrIndexLimit[i] == 0); -+ attrIndexLimit[i] = 32; // just for the sake of predefs. -+ attrDefs[i] = new ArrayList(Collections.nCopies(attrIndexLimit[i], null)); -+ } - -- // Add predefined attribute definitions: -- attrInnerClassesEmpty = -- predefineAttribute(CLASS_ATTR_InnerClasses, ATTR_CONTEXT_CLASS, null, -- "InnerClasses", ""); -- assert(attrInnerClassesEmpty == Package.attrInnerClassesEmpty); -- predefineAttribute(CLASS_ATTR_SourceFile, ATTR_CONTEXT_CLASS, -- new Band[] { class_SourceFile_RUN }, -- "SourceFile", "RUNH"); -- predefineAttribute(CLASS_ATTR_EnclosingMethod, ATTR_CONTEXT_CLASS, -- new Band[] { -- class_EnclosingMethod_RC, -- class_EnclosingMethod_RDN -- }, -- "EnclosingMethod", "RCHRDNH"); -- attrClassFileVersion = -- predefineAttribute(CLASS_ATTR_ClassFile_version, ATTR_CONTEXT_CLASS, -- new Band[] { -- class_ClassFile_version_minor_H, -- class_ClassFile_version_major_H -- }, -- ".ClassFile.version", "HH"); -- predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_CLASS, -- new Band[] { class_Signature_RS }, -- "Signature", "RSH"); -- predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_CLASS, null, -- "Deprecated", ""); -- //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_CLASS, null, -- // "Synthetic", ""); -- predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CLASS, null, -- ".Overflow", ""); -- attrConstantValue = -- predefineAttribute(FIELD_ATTR_ConstantValue, ATTR_CONTEXT_FIELD, -- new Band[] { field_ConstantValue_KQ }, -- "ConstantValue", "KQH"); -- predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_FIELD, -- new Band[] { field_Signature_RS }, -- "Signature", "RSH"); -- predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_FIELD, null, -- "Deprecated", ""); -- //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_FIELD, null, -- // "Synthetic", ""); -- predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_FIELD, null, -- ".Overflow", ""); -- attrCodeEmpty = -- predefineAttribute(METHOD_ATTR_Code, ATTR_CONTEXT_METHOD, null, -- "Code", ""); -- predefineAttribute(METHOD_ATTR_Exceptions, ATTR_CONTEXT_METHOD, -- new Band[] { -- method_Exceptions_N, -- method_Exceptions_RC -- }, -- "Exceptions", "NH[RCH]"); -- assert(attrCodeEmpty == Package.attrCodeEmpty); -- predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_METHOD, -- new Band[] { method_Signature_RS }, -- "Signature", "RSH"); -- predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_METHOD, null, -- "Deprecated", ""); -- //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_METHOD, null, -- // "Synthetic", ""); -- predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_METHOD, null, -- ".Overflow", ""); -+ // Add predefined attribute definitions: -+ attrInnerClassesEmpty = -+ predefineAttribute(CLASS_ATTR_InnerClasses, ATTR_CONTEXT_CLASS, null, -+ "InnerClasses", ""); -+ assert(attrInnerClassesEmpty == Package.attrInnerClassesEmpty); -+ predefineAttribute(CLASS_ATTR_SourceFile, ATTR_CONTEXT_CLASS, -+ new Band[] { class_SourceFile_RUN }, -+ "SourceFile", "RUNH"); -+ predefineAttribute(CLASS_ATTR_EnclosingMethod, ATTR_CONTEXT_CLASS, -+ new Band[] { -+ class_EnclosingMethod_RC, -+ class_EnclosingMethod_RDN -+ }, -+ "EnclosingMethod", "RCHRDNH"); -+ attrClassFileVersion = -+ predefineAttribute(CLASS_ATTR_ClassFile_version, ATTR_CONTEXT_CLASS, -+ new Band[] { -+ class_ClassFile_version_minor_H, -+ class_ClassFile_version_major_H -+ }, -+ ".ClassFile.version", "HH"); -+ predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_CLASS, -+ new Band[] { class_Signature_RS }, -+ "Signature", "RSH"); -+ predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_CLASS, null, -+ "Deprecated", ""); -+ //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_CLASS, null, -+ // "Synthetic", ""); -+ predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CLASS, null, -+ ".Overflow", ""); -+ attrConstantValue = -+ predefineAttribute(FIELD_ATTR_ConstantValue, ATTR_CONTEXT_FIELD, -+ new Band[] { field_ConstantValue_KQ }, -+ "ConstantValue", "KQH"); -+ predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_FIELD, -+ new Band[] { field_Signature_RS }, -+ "Signature", "RSH"); -+ predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_FIELD, null, -+ "Deprecated", ""); -+ //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_FIELD, null, -+ // "Synthetic", ""); -+ predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_FIELD, null, -+ ".Overflow", ""); -+ attrCodeEmpty = -+ predefineAttribute(METHOD_ATTR_Code, ATTR_CONTEXT_METHOD, null, -+ "Code", ""); -+ predefineAttribute(METHOD_ATTR_Exceptions, ATTR_CONTEXT_METHOD, -+ new Band[] { -+ method_Exceptions_N, -+ method_Exceptions_RC -+ }, -+ "Exceptions", "NH[RCH]"); -+ assert(attrCodeEmpty == Package.attrCodeEmpty); -+ predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_METHOD, -+ new Band[] { method_Signature_RS }, -+ "Signature", "RSH"); -+ predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_METHOD, null, -+ "Deprecated", ""); -+ //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_METHOD, null, -+ // "Synthetic", ""); -+ predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_METHOD, null, -+ ".Overflow", ""); - -- for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) { -- MultiBand xxx_metadata_bands = metadataBands[ctype]; -- if (xxx_metadata_bands == null) -- continue; // no code attrs -+ for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) { -+ MultiBand xxx_metadata_bands = metadataBands[ctype]; -+ if (xxx_metadata_bands == null) -+ continue; // no code attrs - -- // These arguments cause the bands to be built -- // automatically for this complicated layout: -- predefineAttribute(X_ATTR_RuntimeVisibleAnnotations, -- ATTR_CONTEXT_NAME[ctype]+"_RVA_", -- xxx_metadata_bands, -- Attribute.lookup(null, ctype, -- "RuntimeVisibleAnnotations")); -- predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations, -- ATTR_CONTEXT_NAME[ctype]+"_RIA_", -- xxx_metadata_bands, -- Attribute.lookup(null, ctype, -- "RuntimeInvisibleAnnotations")); -- if (ctype != ATTR_CONTEXT_METHOD) -- continue; -+ // These arguments cause the bands to be built -+ // automatically for this complicated layout: -+ predefineAttribute(X_ATTR_RuntimeVisibleAnnotations, -+ ATTR_CONTEXT_NAME[ctype]+"_RVA_", -+ xxx_metadata_bands, -+ Attribute.lookup(null, ctype, -+ "RuntimeVisibleAnnotations")); -+ predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations, -+ ATTR_CONTEXT_NAME[ctype]+"_RIA_", -+ xxx_metadata_bands, -+ Attribute.lookup(null, ctype, -+ "RuntimeInvisibleAnnotations")); -+ if (ctype != ATTR_CONTEXT_METHOD) -+ continue; - -- predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations, -- "method_RVPA_", xxx_metadata_bands, -- Attribute.lookup(null, ctype, -- "RuntimeVisibleParameterAnnotations")); -- predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations, -- "method_RIPA_", xxx_metadata_bands, -- Attribute.lookup(null, ctype, -- "RuntimeInvisibleParameterAnnotations")); -- predefineAttribute(METHOD_ATTR_AnnotationDefault, -- "method_AD_", xxx_metadata_bands, -- Attribute.lookup(null, ctype, -- "AnnotationDefault")); -- } -+ predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations, -+ "method_RVPA_", xxx_metadata_bands, -+ Attribute.lookup(null, ctype, -+ "RuntimeVisibleParameterAnnotations")); -+ predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations, -+ "method_RIPA_", xxx_metadata_bands, -+ Attribute.lookup(null, ctype, -+ "RuntimeInvisibleParameterAnnotations")); -+ predefineAttribute(METHOD_ATTR_AnnotationDefault, -+ "method_AD_", xxx_metadata_bands, -+ Attribute.lookup(null, ctype, -+ "AnnotationDefault")); -+ } - - -- Attribute.Layout stackMapDef = Attribute.lookup(null, ATTR_CONTEXT_CODE, "StackMapTable").layout(); -- predefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE, -- stackmap_bands.toArray(), -- stackMapDef.name(), stackMapDef.layout()); -+ Attribute.Layout stackMapDef = Attribute.lookup(null, ATTR_CONTEXT_CODE, "StackMapTable").layout(); -+ predefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE, -+ stackmap_bands.toArray(), -+ stackMapDef.name(), stackMapDef.layout()); - -- predefineAttribute(CODE_ATTR_LineNumberTable, ATTR_CONTEXT_CODE, -- new Band[] { -- code_LineNumberTable_N, -- code_LineNumberTable_bci_P, -- code_LineNumberTable_line -- }, -- "LineNumberTable", "NH[PHH]"); -- predefineAttribute(CODE_ATTR_LocalVariableTable, ATTR_CONTEXT_CODE, -- new Band[] { -- code_LocalVariableTable_N, -- code_LocalVariableTable_bci_P, -- code_LocalVariableTable_span_O, -- code_LocalVariableTable_name_RU, -- code_LocalVariableTable_type_RS, -- code_LocalVariableTable_slot -- }, -- "LocalVariableTable", "NH[PHOHRUHRSHH]"); -- predefineAttribute(CODE_ATTR_LocalVariableTypeTable, ATTR_CONTEXT_CODE, -- new Band[] { -- code_LocalVariableTypeTable_N, -- code_LocalVariableTypeTable_bci_P, -- code_LocalVariableTypeTable_span_O, -- code_LocalVariableTypeTable_name_RU, -- code_LocalVariableTypeTable_type_RS, -- code_LocalVariableTypeTable_slot -- }, -- "LocalVariableTypeTable", "NH[PHOHRUHRSHH]"); -- predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CODE, null, -- ".Overflow", ""); -+ predefineAttribute(CODE_ATTR_LineNumberTable, ATTR_CONTEXT_CODE, -+ new Band[] { -+ code_LineNumberTable_N, -+ code_LineNumberTable_bci_P, -+ code_LineNumberTable_line -+ }, -+ "LineNumberTable", "NH[PHH]"); -+ predefineAttribute(CODE_ATTR_LocalVariableTable, ATTR_CONTEXT_CODE, -+ new Band[] { -+ code_LocalVariableTable_N, -+ code_LocalVariableTable_bci_P, -+ code_LocalVariableTable_span_O, -+ code_LocalVariableTable_name_RU, -+ code_LocalVariableTable_type_RS, -+ code_LocalVariableTable_slot -+ }, -+ "LocalVariableTable", "NH[PHOHRUHRSHH]"); -+ predefineAttribute(CODE_ATTR_LocalVariableTypeTable, ATTR_CONTEXT_CODE, -+ new Band[] { -+ code_LocalVariableTypeTable_N, -+ code_LocalVariableTypeTable_bci_P, -+ code_LocalVariableTypeTable_span_O, -+ code_LocalVariableTypeTable_name_RU, -+ code_LocalVariableTypeTable_type_RS, -+ code_LocalVariableTypeTable_slot -+ }, -+ "LocalVariableTypeTable", "NH[PHOHRUHRSHH]"); -+ predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CODE, null, -+ ".Overflow", ""); - -- // Clear the record of having seen these definitions, -- // so they may be redefined without error. -- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -- attrDefSeen[i] = 0; -- } -+ // Clear the record of having seen these definitions, -+ // so they may be redefined without error. -+ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -+ attrDefSeen[i] = 0; -+ } - -- // Set up the special masks: -- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -- attrOverflowMask[i] = (1<<X_ATTR_OVERFLOW); -- attrIndexLimit[i] = 0; // will make a final decision later -- } -- attrClassFileVersionMask = (1<<CLASS_ATTR_ClassFile_version); -+ // Set up the special masks: -+ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -+ attrOverflowMask[i] = (1<<X_ATTR_OVERFLOW); -+ attrIndexLimit[i] = 0; // will make a final decision later -+ } -+ attrClassFileVersionMask = (1<<CLASS_ATTR_ClassFile_version); - } - - private void adjustToMajver() { -- if (getPackageMajver() < JAVA6_PACKAGE_MAJOR_VERSION) { -- if (verbose > 0) Utils.log.fine("Legacy package version"); -- // Revoke definition of pre-1.6 attribute type. -- undefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE); -- } -+ if (getPackageMajver() < JAVA6_PACKAGE_MAJOR_VERSION) { -+ if (verbose > 0) Utils.log.fine("Legacy package version"); -+ // Revoke definition of pre-1.6 attribute type. -+ undefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE); -+ } - } - - protected void initAttrIndexLimit() { -- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -- assert(attrIndexLimit[i] == 0); // decide on it now! -- attrIndexLimit[i] = (haveFlagsHi(i)? 63: 32); -- assert(attrDefs[i].size() == 32); // all predef indexes are <32 -- int addMore = attrIndexLimit[i] - attrDefs[i].size(); -- attrDefs[i].addAll(Collections.nCopies(addMore, null)); -- } -+ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -+ assert(attrIndexLimit[i] == 0); // decide on it now! -+ attrIndexLimit[i] = (haveFlagsHi(i)? 63: 32); -+ assert(attrDefs[i].size() == 32); // all predef indexes are <32 -+ int addMore = attrIndexLimit[i] - attrDefs[i].size(); -+ attrDefs[i].addAll(Collections.nCopies(addMore, null)); -+ } - } - - protected boolean haveFlagsHi(int ctype) { -- int mask = 1<<(LG_AO_HAVE_XXX_FLAGS_HI+ctype); -- switch (ctype) { -- case ATTR_CONTEXT_CLASS: -- assert(mask == AO_HAVE_CLASS_FLAGS_HI); break; -- case ATTR_CONTEXT_FIELD: -- assert(mask == AO_HAVE_FIELD_FLAGS_HI); break; -- case ATTR_CONTEXT_METHOD: -- assert(mask == AO_HAVE_METHOD_FLAGS_HI); break; -- case ATTR_CONTEXT_CODE: -- assert(mask == AO_HAVE_CODE_FLAGS_HI); break; -- default: -- assert(false); -- } -- return testBit(archiveOptions, mask); -+ int mask = 1<<(LG_AO_HAVE_XXX_FLAGS_HI+ctype); -+ switch (ctype) { -+ case ATTR_CONTEXT_CLASS: -+ assert(mask == AO_HAVE_CLASS_FLAGS_HI); break; -+ case ATTR_CONTEXT_FIELD: -+ assert(mask == AO_HAVE_FIELD_FLAGS_HI); break; -+ case ATTR_CONTEXT_METHOD: -+ assert(mask == AO_HAVE_METHOD_FLAGS_HI); break; -+ case ATTR_CONTEXT_CODE: -+ assert(mask == AO_HAVE_CODE_FLAGS_HI); break; -+ default: -+ assert(false); -+ } -+ return testBit(archiveOptions, mask); - } - - protected ArrayList getPredefinedAttrs(int ctype) { -- assert(attrIndexLimit[ctype] != 0); -- ArrayList res = new ArrayList(attrIndexLimit[ctype]); -- // Remove nulls and non-predefs. -- for (int ai = 0; ai < attrIndexLimit[ctype]; ai++) { -- if (testBit(attrDefSeen[ctype], 1L<<ai)) continue; -- Attribute.Layout def = (Attribute.Layout) attrDefs[ctype].get(ai); -- if (def == null) continue; // unused flag bit -- assert(isPredefinedAttr(ctype, ai)); -- res.add(def); -- } -- return res; -+ assert(attrIndexLimit[ctype] != 0); -+ ArrayList res = new ArrayList(attrIndexLimit[ctype]); -+ // Remove nulls and non-predefs. -+ for (int ai = 0; ai < attrIndexLimit[ctype]; ai++) { -+ if (testBit(attrDefSeen[ctype], 1L<<ai)) continue; -+ Attribute.Layout def = (Attribute.Layout) attrDefs[ctype].get(ai); -+ if (def == null) continue; // unused flag bit -+ assert(isPredefinedAttr(ctype, ai)); -+ res.add(def); -+ } -+ return res; - } - - protected boolean isPredefinedAttr(int ctype, int ai) { -- assert(attrIndexLimit[ctype] != 0); -- // Overflow attrs are never predefined. -- if (ai >= attrIndexLimit[ctype]) return false; -- // If the bit is set, it was explicitly def'd. -- if (testBit(attrDefSeen[ctype], 1L<<ai)) return false; -- return (attrDefs[ctype].get(ai) != null); -+ assert(attrIndexLimit[ctype] != 0); -+ // Overflow attrs are never predefined. -+ if (ai >= attrIndexLimit[ctype]) return false; -+ // If the bit is set, it was explicitly def'd. -+ if (testBit(attrDefSeen[ctype], 1L<<ai)) return false; -+ return (attrDefs[ctype].get(ai) != null); - } - - protected void adjustSpecialAttrMasks() { -- // Clear special masks if new definitions have been seen for them. -- attrClassFileVersionMask &= ~ attrDefSeen[ATTR_CONTEXT_CLASS]; -- // It is possible to clear the overflow mask (bit 16). -- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -- attrOverflowMask[i] &= ~ attrDefSeen[i]; -- } -+ // Clear special masks if new definitions have been seen for them. -+ attrClassFileVersionMask &= ~ attrDefSeen[ATTR_CONTEXT_CLASS]; -+ // It is possible to clear the overflow mask (bit 16). -+ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) { -+ attrOverflowMask[i] &= ~ attrDefSeen[i]; -+ } - } - - protected Attribute makeClassFileVersionAttr(int minver, int majver) { -- byte[] bytes = { -- (byte)(minver >> 8), (byte)minver, -- (byte)(majver >> 8), (byte)majver -- }; -- return attrClassFileVersion.addContent(bytes); -+ byte[] bytes = { -+ (byte)(minver >> 8), (byte)minver, -+ (byte)(majver >> 8), (byte)majver -+ }; -+ return attrClassFileVersion.addContent(bytes); - } - - protected short[] parseClassFileVersionAttr(Attribute attr) { -- assert(attr.layout() == attrClassFileVersion); -- assert(attr.size() == 4); -- byte[] bytes = attr.bytes(); -- int minver = ((bytes[0] & 0xFF) << 8) | (bytes[1] & 0xFF); -- int majver = ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF); -- return new short[]{ (short) minver, (short) majver }; -+ assert(attr.layout() == attrClassFileVersion); -+ assert(attr.size() == 4); -+ byte[] bytes = attr.bytes(); -+ int minver = ((bytes[0] & 0xFF) << 8) | (bytes[1] & 0xFF); -+ int majver = ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF); -+ return new short[]{ (short) minver, (short) majver }; - } - - private boolean assertBandOKForElems(Band[] ab, Attribute.Layout.Element[] elems) { -- for (int i = 0; i < elems.length; i++) { -- assert(assertBandOKForElem(ab, elems[i])); -- } -- return true; -+ for (int i = 0; i < elems.length; i++) { -+ assert(assertBandOKForElem(ab, elems[i])); -+ } -+ return true; - } - private boolean assertBandOKForElem(Band[] ab, Attribute.Layout.Element e) { -- Band b = null; -- if (e.bandIndex != Attribute.NO_BAND_INDEX) -- b = ab[e.bandIndex]; -- Coding rc = UNSIGNED5; -- boolean wantIntBand = true; -- switch (e.kind) { -- case Attribute.EK_INT: -- if (e.flagTest(Attribute.EF_SIGN)) { -- rc = SIGNED5; -- } else if (e.len == 1) { -- rc = BYTE1; -- } -- break; -- case Attribute.EK_BCI: -- if (!e.flagTest(Attribute.EF_DELTA)) { -- rc = BCI5; -- } else { -- rc = BRANCH5; -- } -- break; -- case Attribute.EK_BCO: -- rc = BRANCH5; -- break; -- case Attribute.EK_FLAG: -- if (e.len == 1) rc = BYTE1; -- break; -- case Attribute.EK_REPL: -- if (e.len == 1) rc = BYTE1; -- assertBandOKForElems(ab, e.body); -- break; -- case Attribute.EK_UN: -- if (e.flagTest(Attribute.EF_SIGN)) { -- rc = SIGNED5; -- } else if (e.len == 1) { -- rc = BYTE1; -- } -- assertBandOKForElems(ab, e.body); -- break; -- case Attribute.EK_CASE: -- assert(b == null); -- assertBandOKForElems(ab, e.body); -- return true; // no direct band -- case Attribute.EK_CALL: -- assert(b == null); -- return true; // no direct band -- case Attribute.EK_CBLE: -- assert(b == null); -- assertBandOKForElems(ab, e.body); -- return true; // no direct band -- case Attribute.EK_REF: -- wantIntBand = false; -- assert(b instanceof CPRefBand); -- assert(((CPRefBand)b).nullOK == e.flagTest(Attribute.EF_NULL)); -- break; -- default: assert(false); -- } -- assert(b.regularCoding == rc) -- : (e+" // "+b); -- if (wantIntBand) -- assert(b instanceof IntBand); -- return true; -+ Band b = null; -+ if (e.bandIndex != Attribute.NO_BAND_INDEX) -+ b = ab[e.bandIndex]; -+ Coding rc = UNSIGNED5; -+ boolean wantIntBand = true; -+ switch (e.kind) { -+ case Attribute.EK_INT: -+ if (e.flagTest(Attribute.EF_SIGN)) { -+ rc = SIGNED5; -+ } else if (e.len == 1) { -+ rc = BYTE1; -+ } -+ break; -+ case Attribute.EK_BCI: -+ if (!e.flagTest(Attribute.EF_DELTA)) { -+ rc = BCI5; -+ } else { -+ rc = BRANCH5; -+ } -+ break; -+ case Attribute.EK_BCO: -+ rc = BRANCH5; -+ break; -+ case Attribute.EK_FLAG: -+ if (e.len == 1) rc = BYTE1; -+ break; -+ case Attribute.EK_REPL: -+ if (e.len == 1) rc = BYTE1; -+ assertBandOKForElems(ab, e.body); -+ break; -+ case Attribute.EK_UN: -+ if (e.flagTest(Attribute.EF_SIGN)) { -+ rc = SIGNED5; -+ } else if (e.len == 1) { -+ rc = BYTE1; -+ } -+ assertBandOKForElems(ab, e.body); -+ break; -+ case Attribute.EK_CASE: -+ assert(b == null); -+ assertBandOKForElems(ab, e.body); -+ return true; // no direct band -+ case Attribute.EK_CALL: -+ assert(b == null); -+ return true; // no direct band -+ case Attribute.EK_CBLE: -+ assert(b == null); -+ assertBandOKForElems(ab, e.body); -+ return true; // no direct band -+ case Attribute.EK_REF: -+ wantIntBand = false; -+ assert(b instanceof CPRefBand); -+ assert(((CPRefBand)b).nullOK == e.flagTest(Attribute.EF_NULL)); -+ break; -+ default: assert(false); -+ } -+ assert(b.regularCoding == rc) -+ : (e+" // "+b); -+ if (wantIntBand) -+ assert(b instanceof IntBand); -+ return true; - } - - private - Attribute.Layout predefineAttribute(int index, int ctype, Band[] ab, -- String name, String layout) { -- // Use Attribute.find to get uniquification of layouts. -- Attribute.Layout def = Attribute.find(ctype, name, layout).layout(); -- //def.predef = true; -- if (index >= 0) { -- setAttributeLayoutIndex(def, index); -- } -- if (ab == null) { -- ab = new Band[0]; -- } -- assert(attrBandTable.get(def) == null); // no redef -- attrBandTable.put(def, ab); -- assert(def.bandCount == ab.length) -- : (def+" // "+Arrays.asList(ab)); -- // Let's make sure the band types match: -- assert(assertBandOKForElems(ab, def.elems)); -- return def; -+ String name, String layout) { -+ // Use Attribute.find to get uniquification of layouts. -+ Attribute.Layout def = Attribute.find(ctype, name, layout).layout(); -+ //def.predef = true; -+ if (index >= 0) { -+ setAttributeLayoutIndex(def, index); -+ } -+ if (ab == null) { -+ ab = new Band[0]; -+ } -+ assert(attrBandTable.get(def) == null); // no redef -+ attrBandTable.put(def, ab); -+ assert(def.bandCount == ab.length) -+ : (def+" // "+Arrays.asList(ab)); -+ // Let's make sure the band types match: -+ assert(assertBandOKForElems(ab, def.elems)); -+ return def; - } - - // This version takes bandPrefix/addHere instead of prebuilt Band[] ab. - private - Attribute.Layout predefineAttribute(int index, -- String bandPrefix, MultiBand addHere, -- Attribute attr) { -- //Attribute.Layout def = Attribute.find(ctype, name, layout).layout(); -- Attribute.Layout def = attr.layout(); -- int ctype = def.ctype(); -- return predefineAttribute(index, ctype, -- makeNewAttributeBands(bandPrefix, def, -- addHere), -- def.name(), def.layout()); -+ String bandPrefix, MultiBand addHere, -+ Attribute attr) { -+ //Attribute.Layout def = Attribute.find(ctype, name, layout).layout(); -+ Attribute.Layout def = attr.layout(); -+ int ctype = def.ctype(); -+ return predefineAttribute(index, ctype, -+ makeNewAttributeBands(bandPrefix, def, -+ addHere), -+ def.name(), def.layout()); - } - - private - void undefineAttribute(int index, int ctype) { -- if (verbose > 1) { -- System.out.println("Removing predefined "+ATTR_CONTEXT_NAME[ctype]+ -- " attribute on bit "+index); -- } -- List defList = attrDefs[ctype]; -- Attribute.Layout def = (Attribute.Layout) defList.get(index); -- assert(def != null); -- defList.set(index, null); -- attrIndexTable.put(def, null); -- // Clear the def bit. (For predefs, it's already clear.) -- assert(index < 64); -- attrDefSeen[ctype] &= ~(1L<<index); -- attrFlagMask[ctype] &= ~(1L<<index); -- Band[] ab = (Band[]) attrBandTable.get(def); -- for (int j = 0; j < ab.length; j++) { -- ab[j].doneWithUnusedBand(); -- } -+ if (verbose > 1) { -+ System.out.println("Removing predefined "+ATTR_CONTEXT_NAME[ctype]+ -+ " attribute on bit "+index); -+ } -+ List defList = attrDefs[ctype]; -+ Attribute.Layout def = (Attribute.Layout) defList.get(index); -+ assert(def != null); -+ defList.set(index, null); -+ attrIndexTable.put(def, null); -+ // Clear the def bit. (For predefs, it's already clear.) -+ assert(index < 64); -+ attrDefSeen[ctype] &= ~(1L<<index); -+ attrFlagMask[ctype] &= ~(1L<<index); -+ Band[] ab = (Band[]) attrBandTable.get(def); -+ for (int j = 0; j < ab.length; j++) { -+ ab[j].doneWithUnusedBand(); -+ } - } - - // Bands which contain non-predefined attrs. - protected MultiBand[] attrBands = new MultiBand[ATTR_CONTEXT_LIMIT]; - { -- attrBands[ATTR_CONTEXT_CLASS] = class_attr_bands; -- attrBands[ATTR_CONTEXT_FIELD] = field_attr_bands; -- attrBands[ATTR_CONTEXT_METHOD] = method_attr_bands; -- attrBands[ATTR_CONTEXT_CODE] = code_attr_bands; -+ attrBands[ATTR_CONTEXT_CLASS] = class_attr_bands; -+ attrBands[ATTR_CONTEXT_FIELD] = field_attr_bands; -+ attrBands[ATTR_CONTEXT_METHOD] = method_attr_bands; -+ attrBands[ATTR_CONTEXT_CODE] = code_attr_bands; - } - - // Create bands for all non-predefined attrs. - void makeNewAttributeBands() { -- // Retract special flag bit bindings, if they were taken over. -- adjustSpecialAttrMasks(); -+ // Retract special flag bit bindings, if they were taken over. -+ adjustSpecialAttrMasks(); - -- for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) { -- String cname = ATTR_CONTEXT_NAME[ctype]; -- MultiBand xxx_attr_bands = attrBands[ctype]; -- long defSeen = attrDefSeen[ctype]; -- // Note: attrDefSeen is always a subset of attrFlagMask. -- assert((defSeen & ~attrFlagMask[ctype]) == 0); -- for (int i = 0; i < attrDefs[ctype].size(); i++) { -- Attribute.Layout def = (Attribute.Layout) -- attrDefs[ctype].get(i); -- if (def == null) continue; // unused flag bit -- if (def.bandCount == 0) continue; // empty attr -- if (i < attrIndexLimit[ctype] && !testBit(defSeen, 1L<<i)) { -- // There are already predefined bands here. -- assert(attrBandTable.get(def) != null); -- continue; -- } -- int base = xxx_attr_bands.size(); -- String pfx = cname+"_"+def.name()+"_"; // debug only -- if (verbose > 1) -- Utils.log.fine("Making new bands for "+def); -- Band[] newAB = makeNewAttributeBands(pfx, def, -- xxx_attr_bands); -- assert(newAB.length == def.bandCount); -- Band[] prevAB = (Band[]) attrBandTable.put(def, newAB); -- if (prevAB != null) { -- // We won't be using these predefined bands. -- for (int j = 0; j < prevAB.length; j++) { -- prevAB[j].doneWithUnusedBand(); -- } -- } -- } -- } -- //System.out.println(prevForAssertMap); -+ for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) { -+ String cname = ATTR_CONTEXT_NAME[ctype]; -+ MultiBand xxx_attr_bands = attrBands[ctype]; -+ long defSeen = attrDefSeen[ctype]; -+ // Note: attrDefSeen is always a subset of attrFlagMask. -+ assert((defSeen & ~attrFlagMask[ctype]) == 0); -+ for (int i = 0; i < attrDefs[ctype].size(); i++) { -+ Attribute.Layout def = (Attribute.Layout) -+ attrDefs[ctype].get(i); -+ if (def == null) continue; // unused flag bit -+ if (def.bandCount == 0) continue; // empty attr -+ if (i < attrIndexLimit[ctype] && !testBit(defSeen, 1L<<i)) { -+ // There are already predefined bands here. -+ assert(attrBandTable.get(def) != null); -+ continue; -+ } -+ int base = xxx_attr_bands.size(); -+ String pfx = cname+"_"+def.name()+"_"; // debug only -+ if (verbose > 1) -+ Utils.log.fine("Making new bands for "+def); -+ Band[] newAB = makeNewAttributeBands(pfx, def, -+ xxx_attr_bands); -+ assert(newAB.length == def.bandCount); -+ Band[] prevAB = (Band[]) attrBandTable.put(def, newAB); -+ if (prevAB != null) { -+ // We won't be using these predefined bands. -+ for (int j = 0; j < prevAB.length; j++) { -+ prevAB[j].doneWithUnusedBand(); -+ } -+ } -+ } -+ } -+ //System.out.println(prevForAssertMap); - } - private - Band[] makeNewAttributeBands(String pfx, Attribute.Layout def, -- MultiBand addHere) { -- int base = addHere.size(); -- makeNewAttributeBands(pfx, def.elems, addHere); -- int nb = addHere.size() - base; -- Band[] newAB = new Band[nb]; -- for (int i = 0; i < nb; i++) { -- newAB[i] = addHere.get(base+i); -- } -- return newAB; -+ MultiBand addHere) { -+ int base = addHere.size(); -+ makeNewAttributeBands(pfx, def.elems, addHere); -+ int nb = addHere.size() - base; -+ Band[] newAB = new Band[nb]; -+ for (int i = 0; i < nb; i++) { -+ newAB[i] = addHere.get(base+i); -+ } -+ return newAB; - } - // Recursive helper, operates on a "body" or other sequence of elems: - private - void makeNewAttributeBands(String pfx, Attribute.Layout.Element[] elems, -- MultiBand ab) { -- for (int i = 0; i < elems.length; i++) { -- Attribute.Layout.Element e = elems[i]; -- String name = pfx+ab.size()+"_"+e.layout; -- { -- int tem; -- if ((tem = name.indexOf('[')) > 0) -- name = name.substring(0, tem); -- if ((tem = name.indexOf('(')) > 0) -- name = name.substring(0, tem); -- if (name.endsWith("H")) -- name = name.substring(0, name.length()-1); -- } -- Band nb; -- switch (e.kind) { -- case Attribute.EK_INT: -- nb = newElemBand(e, name, ab); -- break; -- case Attribute.EK_BCI: -- if (!e.flagTest(Attribute.EF_DELTA)) { -- // PH: transmit R(bci), store bci -- nb = ab.newIntBand(name, BCI5); -- } else { -- // POH: transmit D(R(bci)), store bci -- nb = ab.newIntBand(name, BRANCH5); -- } -- // Note: No case for BYTE1 here. -- break; -- case Attribute.EK_BCO: -- // OH: transmit D(R(bci)), store D(bci) -- nb = ab.newIntBand(name, BRANCH5); -- // Note: No case for BYTE1 here. -- break; -- case Attribute.EK_FLAG: -- assert(!e.flagTest(Attribute.EF_SIGN)); -- nb = newElemBand(e, name, ab); -- break; -- case Attribute.EK_REPL: -- assert(!e.flagTest(Attribute.EF_SIGN)); -- nb = newElemBand(e, name, ab); -- makeNewAttributeBands(pfx, e.body, ab); -- break; -- case Attribute.EK_UN: -- nb = newElemBand(e, name, ab); -- makeNewAttributeBands(pfx, e.body, ab); -- break; -- case Attribute.EK_CASE: -- if (!e.flagTest(Attribute.EF_BACK)) { -- // If it's not a duplicate body, make the bands. -- makeNewAttributeBands(pfx, e.body, ab); -- } -- continue; // no new band to make -- case Attribute.EK_REF: -- byte refKind = e.refKind; -- boolean nullOK = e.flagTest(Attribute.EF_NULL); -- nb = ab.newCPRefBand(name, UNSIGNED5, refKind, nullOK); -- // Note: No case for BYTE1 here. -- break; -- case Attribute.EK_CALL: -- continue; // no new band to make -- case Attribute.EK_CBLE: -- makeNewAttributeBands(pfx, e.body, ab); -- continue; // no new band to make -- default: assert(false); continue; -- } -- if (verbose > 1) { -- Utils.log.fine("New attribute band "+nb); -- } -- } -+ MultiBand ab) { -+ for (int i = 0; i < elems.length; i++) { -+ Attribute.Layout.Element e = elems[i]; -+ String name = pfx+ab.size()+"_"+e.layout; -+ { -+ int tem; -+ if ((tem = name.indexOf('[')) > 0) -+ name = name.substring(0, tem); -+ if ((tem = name.indexOf('(')) > 0) -+ name = name.substring(0, tem); -+ if (name.endsWith("H")) -+ name = name.substring(0, name.length()-1); -+ } -+ Band nb; -+ switch (e.kind) { -+ case Attribute.EK_INT: -+ nb = newElemBand(e, name, ab); -+ break; -+ case Attribute.EK_BCI: -+ if (!e.flagTest(Attribute.EF_DELTA)) { -+ // PH: transmit R(bci), store bci -+ nb = ab.newIntBand(name, BCI5); -+ } else { -+ // POH: transmit D(R(bci)), store bci -+ nb = ab.newIntBand(name, BRANCH5); -+ } -+ // Note: No case for BYTE1 here. -+ break; -+ case Attribute.EK_BCO: -+ // OH: transmit D(R(bci)), store D(bci) -+ nb = ab.newIntBand(name, BRANCH5); -+ // Note: No case for BYTE1 here. -+ break; -+ case Attribute.EK_FLAG: -+ assert(!e.flagTest(Attribute.EF_SIGN)); -+ nb = newElemBand(e, name, ab); -+ break; -+ case Attribute.EK_REPL: -+ assert(!e.flagTest(Attribute.EF_SIGN)); -+ nb = newElemBand(e, name, ab); -+ makeNewAttributeBands(pfx, e.body, ab); -+ break; -+ case Attribute.EK_UN: -+ nb = newElemBand(e, name, ab); -+ makeNewAttributeBands(pfx, e.body, ab); -+ break; -+ case Attribute.EK_CASE: -+ if (!e.flagTest(Attribute.EF_BACK)) { -+ // If it's not a duplicate body, make the bands. -+ makeNewAttributeBands(pfx, e.body, ab); -+ } -+ continue; // no new band to make -+ case Attribute.EK_REF: -+ byte refKind = e.refKind; -+ boolean nullOK = e.flagTest(Attribute.EF_NULL); -+ nb = ab.newCPRefBand(name, UNSIGNED5, refKind, nullOK); -+ // Note: No case for BYTE1 here. -+ break; -+ case Attribute.EK_CALL: -+ continue; // no new band to make -+ case Attribute.EK_CBLE: -+ makeNewAttributeBands(pfx, e.body, ab); -+ continue; // no new band to make -+ default: assert(false); continue; -+ } -+ if (verbose > 1) { -+ Utils.log.fine("New attribute band "+nb); -+ } -+ } - } - private - Band newElemBand(Attribute.Layout.Element e, String name, MultiBand ab) { -- if (e.flagTest(Attribute.EF_SIGN)) { -- return ab.newIntBand(name, SIGNED5); -- } else if (e.len == 1) { -- return ab.newIntBand(name, BYTE1); // Not ByteBand, please. -- } else { -- return ab.newIntBand(name, UNSIGNED5); -- } -+ if (e.flagTest(Attribute.EF_SIGN)) { -+ return ab.newIntBand(name, SIGNED5); -+ } else if (e.len == 1) { -+ return ab.newIntBand(name, BYTE1); // Not ByteBand, please. -+ } else { -+ return ab.newIntBand(name, UNSIGNED5); -+ } - } - - protected int setAttributeLayoutIndex(Attribute.Layout def, int index) { -- int ctype = def.ctype; -- assert(ATTR_INDEX_OVERFLOW <= index && index < attrIndexLimit[ctype]); -- List defList = attrDefs[ctype]; -- if (index == ATTR_INDEX_OVERFLOW) { -- // Overflow attribute. -- index = defList.size(); -- defList.add(def); -- if (verbose > 0) -- Utils.log.info("Adding new attribute at "+def +": "+index); -- attrIndexTable.put(def, new Integer(index)); -- return index; -- } -+ int ctype = def.ctype; -+ assert(ATTR_INDEX_OVERFLOW <= index && index < attrIndexLimit[ctype]); -+ List defList = attrDefs[ctype]; -+ if (index == ATTR_INDEX_OVERFLOW) { -+ // Overflow attribute. -+ index = defList.size(); -+ defList.add(def); -+ if (verbose > 0) -+ Utils.log.info("Adding new attribute at "+def +": "+index); -+ attrIndexTable.put(def, new Integer(index)); -+ return index; -+ } - -- // Detect redefinitions: -- if (testBit(attrDefSeen[ctype], 1L<<index)) { -- throw new RuntimeException("Multiple explicit definition at "+index+": "+def); -- } -- attrDefSeen[ctype] |= (1L<<index); -+ // Detect redefinitions: -+ if (testBit(attrDefSeen[ctype], 1L<<index)) { -+ throw new RuntimeException("Multiple explicit definition at "+index+": "+def); -+ } -+ attrDefSeen[ctype] |= (1L<<index); - -- // Adding a new fixed attribute. -- assert(0 <= index && index < attrIndexLimit[ctype]); -- if (verbose > (attrClassFileVersionMask == 0? 2:0)) -- Utils.log.fine("Fixing new attribute at "+index -- +": "+def -- +(defList.get(index) == null? "": -- "; replacing "+defList.get(index))); -- attrFlagMask[ctype] |= (1L<<index); -- // Remove index binding of any previous fixed attr. -- attrIndexTable.put(defList.get(index), null); -- defList.set(index, def); -- attrIndexTable.put(def, new Integer(index)); -- return index; -+ // Adding a new fixed attribute. -+ assert(0 <= index && index < attrIndexLimit[ctype]); -+ if (verbose > (attrClassFileVersionMask == 0? 2:0)) -+ Utils.log.fine("Fixing new attribute at "+index -+ +": "+def -+ +(defList.get(index) == null? "": -+ "; replacing "+defList.get(index))); -+ attrFlagMask[ctype] |= (1L<<index); -+ // Remove index binding of any previous fixed attr. -+ attrIndexTable.put(defList.get(index), null); -+ defList.set(index, def); -+ attrIndexTable.put(def, new Integer(index)); -+ return index; - } - - // encodings found in the code_headers band - private static final int[][] shortCodeLimits = { -- { 12, 12 }, // s<12, l<12, e=0 [1..144] -- { 8, 8 }, // s<8, l<8, e=1 [145..208] -- { 7, 7 }, // s<7, l<7, e=2 [209..256] -+ { 12, 12 }, // s<12, l<12, e=0 [1..144] -+ { 8, 8 }, // s<8, l<8, e=1 [145..208] -+ { 7, 7 }, // s<7, l<7, e=2 [209..256] - }; - public final int shortCodeHeader_h_limit = shortCodeLimits.length; - - // return 0 if it won't encode, else a number in [1..255] - static int shortCodeHeader(Code code) { -- int s = code.max_stack; -- int l0 = code.max_locals; -- int h = code.handler_class.length; -- if (h >= shortCodeLimits.length) return LONG_CODE_HEADER; -- int siglen = code.getMethod().getArgumentSize(); -- assert(l0 >= siglen); // enough locals for signature! -- if (l0 < siglen) return LONG_CODE_HEADER; -- int l1 = l0 - siglen; // do not count locals required by the signature -- int lims = shortCodeLimits[h][0]; -- int liml = shortCodeLimits[h][1]; -- if (s >= lims || l1 >= liml) return LONG_CODE_HEADER; -- int sc = shortCodeHeader_h_base(h); -- sc += s + lims*l1; -- if (sc > 255) return LONG_CODE_HEADER; -- assert(shortCodeHeader_max_stack(sc) == s); -- assert(shortCodeHeader_max_na_locals(sc) == l1); -- assert(shortCodeHeader_handler_count(sc) == h); -- return sc; -+ int s = code.max_stack; -+ int l0 = code.max_locals; -+ int h = code.handler_class.length; -+ if (h >= shortCodeLimits.length) return LONG_CODE_HEADER; -+ int siglen = code.getMethod().getArgumentSize(); -+ assert(l0 >= siglen); // enough locals for signature! -+ if (l0 < siglen) return LONG_CODE_HEADER; -+ int l1 = l0 - siglen; // do not count locals required by the signature -+ int lims = shortCodeLimits[h][0]; -+ int liml = shortCodeLimits[h][1]; -+ if (s >= lims || l1 >= liml) return LONG_CODE_HEADER; -+ int sc = shortCodeHeader_h_base(h); -+ sc += s + lims*l1; -+ if (sc > 255) return LONG_CODE_HEADER; -+ assert(shortCodeHeader_max_stack(sc) == s); -+ assert(shortCodeHeader_max_na_locals(sc) == l1); -+ assert(shortCodeHeader_handler_count(sc) == h); -+ return sc; - } - - static final int LONG_CODE_HEADER = 0; - static int shortCodeHeader_handler_count(int sc) { -- assert(sc > 0 && sc <= 255); -- for (int h = 0; ; h++) { -- if (sc < shortCodeHeader_h_base(h+1)) -- return h; -- } -+ assert(sc > 0 && sc <= 255); -+ for (int h = 0; ; h++) { -+ if (sc < shortCodeHeader_h_base(h+1)) -+ return h; -+ } - } - static int shortCodeHeader_max_stack(int sc) { -- int h = shortCodeHeader_handler_count(sc); -- int lims = shortCodeLimits[h][0]; -- return (sc - shortCodeHeader_h_base(h)) % lims; -+ int h = shortCodeHeader_handler_count(sc); -+ int lims = shortCodeLimits[h][0]; -+ return (sc - shortCodeHeader_h_base(h)) % lims; - } - static int shortCodeHeader_max_na_locals(int sc) { -- int h = shortCodeHeader_handler_count(sc); -- int lims = shortCodeLimits[h][0]; -- return (sc - shortCodeHeader_h_base(h)) / lims; -+ int h = shortCodeHeader_handler_count(sc); -+ int lims = shortCodeLimits[h][0]; -+ return (sc - shortCodeHeader_h_base(h)) / lims; - } - - private static int shortCodeHeader_h_base(int h) { -- assert(h <= shortCodeLimits.length); -- int sc = 1; -- for (int h0 = 0; h0 < h; h0++) { -- int lims = shortCodeLimits[h0][0]; -- int liml = shortCodeLimits[h0][1]; -- sc += lims * liml; -- } -- return sc; -+ assert(h <= shortCodeLimits.length); -+ int sc = 1; -+ for (int h0 = 0; h0 < h; h0++) { -+ int lims = shortCodeLimits[h0][0]; -+ int liml = shortCodeLimits[h0][1]; -+ sc += lims * liml; -+ } -+ return sc; - } - - // utilities for accessing the bc_label band: - protected void putLabel(IntBand bc_label, Code c, int pc, int targetPC) { -- bc_label.putInt(c.encodeBCI(targetPC) - c.encodeBCI(pc)); -+ bc_label.putInt(c.encodeBCI(targetPC) - c.encodeBCI(pc)); - } - protected int getLabel(IntBand bc_label, Code c, int pc) { -- return c.decodeBCI(bc_label.getInt() + c.encodeBCI(pc)); -+ return c.decodeBCI(bc_label.getInt() + c.encodeBCI(pc)); - } - - protected CPRefBand getCPRefOpBand(int bc) { -- switch (Instruction.getCPRefOpTag(bc)) { -- case CONSTANT_Class: -- return bc_classref; -- case CONSTANT_Fieldref: -- return bc_fieldref; -- case CONSTANT_Methodref: -- return bc_methodref; -- case CONSTANT_InterfaceMethodref: -- return bc_imethodref; -- case CONSTANT_Literal: -- switch (bc) { -- case _ildc: case _ildc_w: -- return bc_intref; -- case _fldc: case _fldc_w: -- return bc_floatref; -- case _lldc2_w: -- return bc_longref; -- case _dldc2_w: -- return bc_doubleref; -- case _aldc: case _aldc_w: -- return bc_stringref; -- case _cldc: case _cldc_w: -- return bc_classref; -- } -- break; -- } -- assert(false); -- return null; -+ switch (Instruction.getCPRefOpTag(bc)) { -+ case CONSTANT_Class: -+ return bc_classref; -+ case CONSTANT_Fieldref: -+ return bc_fieldref; -+ case CONSTANT_Methodref: -+ return bc_methodref; -+ case CONSTANT_InterfaceMethodref: -+ return bc_imethodref; -+ case CONSTANT_Literal: -+ switch (bc) { -+ case _ildc: case _ildc_w: -+ return bc_intref; -+ case _fldc: case _fldc_w: -+ return bc_floatref; -+ case _lldc2_w: -+ return bc_longref; -+ case _dldc2_w: -+ return bc_doubleref; -+ case _aldc: case _aldc_w: -+ return bc_stringref; -+ case _cldc: case _cldc_w: -+ return bc_classref; -+ } -+ break; -+ } -+ assert(false); -+ return null; - } - - protected CPRefBand selfOpRefBand(int self_bc) { -- assert(Instruction.isSelfLinkerOp(self_bc)); -- int idx = (self_bc - _self_linker_op); -- boolean isSuper = (idx >= _self_linker_super_flag); -- if (isSuper) idx -= _self_linker_super_flag; -- boolean isAload = (idx >= _self_linker_aload_flag); -- if (isAload) idx -= _self_linker_aload_flag; -- int origBC = _first_linker_op + idx; -- boolean isField = Instruction.isFieldOp(origBC); -- if (!isSuper) -- return isField? bc_thisfield: bc_thismethod; -- else -- return isField? bc_superfield: bc_supermethod; -+ assert(Instruction.isSelfLinkerOp(self_bc)); -+ int idx = (self_bc - _self_linker_op); -+ boolean isSuper = (idx >= _self_linker_super_flag); -+ if (isSuper) idx -= _self_linker_super_flag; -+ boolean isAload = (idx >= _self_linker_aload_flag); -+ if (isAload) idx -= _self_linker_aload_flag; -+ int origBC = _first_linker_op + idx; -+ boolean isField = Instruction.isFieldOp(origBC); -+ if (!isSuper) -+ return isField? bc_thisfield: bc_thismethod; -+ else -+ return isField? bc_superfield: bc_supermethod; - } - - //////////////////////////////////////////////////////////////////// -@@ -2347,317 +2347,319 @@ class BandStructure implements Constants - static int nextSeqForDebug; - static File dumpDir; - static OutputStream getDumpStream(Band b, String ext) throws IOException { -- return getDumpStream(b.name, b.seqForDebug, ext, b); -+ return getDumpStream(b.name, b.seqForDebug, ext, b); - } - static OutputStream getDumpStream(Index ix, String ext) throws IOException { -- if (ix.size() == 0) return new ByteArrayOutputStream(); -- int seq = ConstantPool.TAG_ORDER[ix.cpMap[0].tag]; -- return getDumpStream(ix.debugName, seq, ext, ix); -+ if (ix.size() == 0) return new ByteArrayOutputStream(); -+ int seq = ConstantPool.TAG_ORDER[ix.cpMap[0].tag]; -+ return getDumpStream(ix.debugName, seq, ext, ix); - } - static OutputStream getDumpStream(String name, int seq, String ext, Object b) throws IOException { -- if (dumpDir == null) { -- dumpDir = File.createTempFile("BD_", "", new File(".")); -- dumpDir.delete(); -- if (dumpDir.mkdir()) -- Utils.log.info("Dumping bands to "+dumpDir); -- } -- name = name.replace('(', ' ').replace(')', ' '); -- name = name.replace('/', ' '); -- name = name.replace('*', ' '); -- name = name.trim().replace(' ','_'); -- name = ((10000+seq) + "_" + name).substring(1); -- File dumpFile = new File(dumpDir, name+ext); -- Utils.log.info("Dumping "+b+" to "+dumpFile); -- return new BufferedOutputStream(new FileOutputStream(dumpFile)); -+ if (dumpDir == null) { -+ dumpDir = File.createTempFile("BD_", "", new File(".")); -+ dumpDir.delete(); -+ if (dumpDir.mkdir()) -+ Utils.log.info("Dumping bands to "+dumpDir); -+ } -+ name = name.replace('(', ' ').replace(')', ' '); -+ name = name.replace('/', ' '); -+ name = name.replace('*', ' '); -+ name = name.trim().replace(' ','_'); -+ name = ((10000+seq) + "_" + name).substring(1); -+ File dumpFile = new File(dumpDir, name+ext); -+ Utils.log.info("Dumping "+b+" to "+dumpFile); -+ return new BufferedOutputStream(new FileOutputStream(dumpFile)); - } - - // DEBUG ONLY: Validate me at each length change. - static boolean assertCanChangeLength(Band b) { -- switch (b.phase) { -- case COLLECT_PHASE: -- case READ_PHASE: -- return true; -- } -- return false; -+ switch (b.phase) { -+ case COLLECT_PHASE: -+ case READ_PHASE: -+ return true; -+ } -+ return false; - } - - // DEBUG ONLY: Validate a phase. - static boolean assertPhase(Band b, int phaseExpected) { -- if (b.phase() != phaseExpected) { -- Utils.log.warning("phase expected "+phaseExpected+" was "+b.phase()+" in "+b); -- return false; -- } -- return true; -+ if (b.phase() != phaseExpected) { -+ Utils.log.warning("phase expected "+phaseExpected+" was "+b.phase()+" in "+b); -+ return false; -+ } -+ return true; - } - - - // DEBUG ONLY: Tells whether verbosity is turned on. - static int verbose() { -- return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE); -+ return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE); - } - - - // DEBUG ONLY: Validate me at each phase change. - static boolean assertPhaseChangeOK(Band b, int p0, int p1) { -- switch (p0*10+p1) { -- /// Writing phases: -- case NO_PHASE*10+COLLECT_PHASE: -- // Ready to collect data from the input classes. -- assert(!b.isReader()); -- assert(b.capacity() >= 0); -- assert(b.length() == 0); -- return true; -- case COLLECT_PHASE*10+FROZEN_PHASE: -- case FROZEN_PHASE*10+FROZEN_PHASE: -- assert(b.length() == 0); -- return true; -- case COLLECT_PHASE*10+WRITE_PHASE: -- case FROZEN_PHASE*10+WRITE_PHASE: -- // Data is all collected. Ready to write bytes to disk. -- return true; -- case WRITE_PHASE*10+DONE_PHASE: -- // Done writing to disk. Ready to reset, in principle. -- return true; -+ switch (p0*10+p1) { -+ /// Writing phases: -+ case NO_PHASE*10+COLLECT_PHASE: -+ // Ready to collect data from the input classes. -+ assert(!b.isReader()); -+ assert(b.capacity() >= 0); -+ assert(b.length() == 0); -+ return true; -+ case COLLECT_PHASE*10+FROZEN_PHASE: -+ case FROZEN_PHASE*10+FROZEN_PHASE: -+ assert(b.length() == 0); -+ return true; -+ case COLLECT_PHASE*10+WRITE_PHASE: -+ case FROZEN_PHASE*10+WRITE_PHASE: -+ // Data is all collected. Ready to write bytes to disk. -+ return true; -+ case WRITE_PHASE*10+DONE_PHASE: -+ // Done writing to disk. Ready to reset, in principle. -+ return true; - -- /// Reading phases: -- case NO_PHASE*10+EXPECT_PHASE: -- assert(b.isReader()); -- assert(b.capacity() < 0); -- return true; -- case EXPECT_PHASE*10+READ_PHASE: -- // Ready to read values from disk. -- assert(Math.max(0,b.capacity()) >= b.valuesExpected()); -- assert(b.length() <= 0); -- return true; -- case READ_PHASE*10+DISBURSE_PHASE: -- // Ready to disburse values. -- assert(b.valuesRemainingForDebug() == b.length()); -- return true; -- case DISBURSE_PHASE*10+DONE_PHASE: -- // Done disbursing values. Ready to reset, in principle. -- assert(assertDoneDisbursing(b)); -- return true; -- } -- if (p0 == p1) -- Utils.log.warning("Already in phase "+p0); -- else -- Utils.log.warning("Unexpected phase "+p0+" -> "+p1); -- return false; -+ /// Reading phases: -+ case NO_PHASE*10+EXPECT_PHASE: -+ assert(b.isReader()); -+ assert(b.capacity() < 0); -+ return true; -+ case EXPECT_PHASE*10+READ_PHASE: -+ // Ready to read values from disk. -+ assert(Math.max(0,b.capacity()) >= b.valuesExpected()); -+ assert(b.length() <= 0); -+ return true; -+ case READ_PHASE*10+DISBURSE_PHASE: -+ // Ready to disburse values. -+ assert(b.valuesRemainingForDebug() == b.length()); -+ return true; -+ case DISBURSE_PHASE*10+DONE_PHASE: -+ // Done disbursing values. Ready to reset, in principle. -+ assert(assertDoneDisbursing(b)); -+ return true; -+ } -+ if (p0 == p1) -+ Utils.log.warning("Already in phase "+p0); -+ else -+ Utils.log.warning("Unexpected phase "+p0+" -> "+p1); -+ return false; - } - - static private boolean assertDoneDisbursing(Band b) { -- if (b.phase != DISBURSE_PHASE) { -- Utils.log.warning("assertDoneDisbursing: still in phase "+b.phase+": "+b); -- if (verbose() <= 1) return false; // fail now -- } -- int left = b.valuesRemainingForDebug(); -- if (left > 0) { -- Utils.log.warning("assertDoneDisbursing: "+left+" values left in "+b); -- if (verbose() <= 1) return false; // fail now -- } -- if (b instanceof MultiBand) { -- MultiBand mb = (MultiBand) b; -- for (int i = 0; i < mb.bandCount; i++) { -- Band sub = mb.bands[i]; -- if (sub.phase != DONE_PHASE) { -- Utils.log.warning("assertDoneDisbursing: sub-band still in phase "+sub.phase+": "+sub); -- if (verbose() <= 1) return false; // fail now -- } -- } -- } -- return true; -+ if (b.phase != DISBURSE_PHASE) { -+ Utils.log.warning("assertDoneDisbursing: still in phase "+b.phase+": "+b); -+ if (verbose() <= 1) return false; // fail now -+ } -+ int left = b.valuesRemainingForDebug(); -+ if (left > 0) { -+ Utils.log.warning("assertDoneDisbursing: "+left+" values left in "+b); -+ if (verbose() <= 1) return false; // fail now -+ } -+ if (b instanceof MultiBand) { -+ MultiBand mb = (MultiBand) b; -+ for (int i = 0; i < mb.bandCount; i++) { -+ Band sub = mb.bands[i]; -+ if (sub.phase != DONE_PHASE) { -+ Utils.log.warning("assertDoneDisbursing: sub-band still in phase "+sub.phase+": "+sub); -+ if (verbose() <= 1) return false; // fail now -+ } -+ } -+ } -+ return true; - } - - static private void printCDecl(Band b) { -- if (b instanceof MultiBand) { -- MultiBand mb = (MultiBand) b; -- for (int i = 0; i < mb.bandCount; i++) { -- printCDecl(mb.bands[i]); -- } -- return; -- } -- String ixS = "NULL"; -- if (b instanceof CPRefBand) { -- Index ix = ((CPRefBand)b).index; -- if (ix != null) ixS = "INDEX("+ix.debugName+")"; -- } -- Coding[] knownc = { BYTE1, CHAR3, BCI5, BRANCH5, UNSIGNED5, -- UDELTA5, SIGNED5, DELTA5, MDELTA5 }; -- String[] knowns = { "BYTE1", "CHAR3", "BCI5", "BRANCH5", "UNSIGNED5", -- "UDELTA5", "SIGNED5", "DELTA5", "MDELTA5" }; -- Coding rc = b.regularCoding; -- int rci = Arrays.asList(knownc).indexOf(rc); -- String cstr; -- if (rci >= 0) -- cstr = knowns[rci]; -- else -- cstr = "CODING"+rc.keyString(); -- System.out.println(" BAND_INIT(\""+b.name()+"\"" -- +", "+cstr+", "+ixS+"),"); -+ if (b instanceof MultiBand) { -+ MultiBand mb = (MultiBand) b; -+ for (int i = 0; i < mb.bandCount; i++) { -+ printCDecl(mb.bands[i]); -+ } -+ return; -+ } -+ String ixS = "NULL"; -+ if (b instanceof CPRefBand) { -+ Index ix = ((CPRefBand)b).index; -+ if (ix != null) ixS = "INDEX("+ix.debugName+")"; -+ } -+ Coding[] knownc = { BYTE1, CHAR3, BCI5, BRANCH5, UNSIGNED5, -+ UDELTA5, SIGNED5, DELTA5, MDELTA5 }; -+ String[] knowns = { "BYTE1", "CHAR3", "BCI5", "BRANCH5", "UNSIGNED5", -+ "UDELTA5", "SIGNED5", "DELTA5", "MDELTA5" }; -+ Coding rc = b.regularCoding; -+ int rci = Arrays.asList(knownc).indexOf(rc); -+ String cstr; -+ if (rci >= 0) -+ cstr = knowns[rci]; -+ else -+ cstr = "CODING"+rc.keyString(); -+ System.out.println(" BAND_INIT(\""+b.name()+"\"" -+ +", "+cstr+", "+ixS+"),"); - } - - private HashMap prevForAssertMap; - - // DEBUG ONLY: Record something about the band order. - boolean notePrevForAssert(Band b, Band p) { -- if (prevForAssertMap == null) -- prevForAssertMap = new HashMap(); -- prevForAssertMap.put(b, p); -- return true; -+ if (prevForAssertMap == null) -+ prevForAssertMap = new HashMap(); -+ prevForAssertMap.put(b, p); -+ return true; - } - - // DEBUG ONLY: Validate next input band. - private boolean assertReadyToReadFrom(Band b, InputStream in) throws IOException { -- Band p = (Band) prevForAssertMap.get(b); -- // Any previous band must be done reading before this one starts. -- if (p != null && phaseCmp(p.phase(), DISBURSE_PHASE) < 0) { -- Utils.log.warning("Previous band not done reading."); -- Utils.log.info(" Previous band: "+p); -- Utils.log.info(" Next band: "+b); -- Thread.dumpStack(); -- assert(verbose > 0); // die unless verbose is true -- } -- String name = b.name; -- if (optDebugBands && !name.startsWith("(")) { -- // Verify synchronization between reader & writer: -- StringBuffer buf = new StringBuffer(); -- int ch; -- while ((ch = in.read()) > 0) -- buf.append((char)ch); -- String inName = buf.toString(); -- if (!inName.equals(name)) { -- StringBuffer sb = new StringBuffer(); -- sb.append("Expected "+name+" but read: "); -- inName += (char)ch; -- while (inName.length() < 10) -- inName += (char)in.read(); -- for (int i = 0; i < inName.length(); i++) -- sb.append(inName.charAt(i)); -- Utils.log.warning(sb.toString()); -- return false; -- } -- } -- return true; -+ Band p = (Band) prevForAssertMap.get(b); -+ // Any previous band must be done reading before this one starts. -+ if (p != null && phaseCmp(p.phase(), DISBURSE_PHASE) < 0) { -+ Utils.log.warning("Previous band not done reading."); -+ Utils.log.info(" Previous band: "+p); -+ Utils.log.info(" Next band: "+b); -+ Thread.dumpStack(); -+ assert(verbose > 0); // die unless verbose is true -+ } -+ String name = b.name; -+ if (optDebugBands && !name.startsWith("(")) { -+ // Verify synchronization between reader & writer: -+ StringBuffer buf = new StringBuffer(); -+ int ch; -+ while ((ch = in.read()) > 0) -+ buf.append((char)ch); -+ String inName = buf.toString(); -+ if (!inName.equals(name)) { -+ StringBuffer sb = new StringBuffer(); -+ sb.append("Expected "+name+" but read: "); -+ inName += (char)ch; -+ while (inName.length() < 10) -+ inName += (char)in.read(); -+ for (int i = 0; i < inName.length(); i++) -+ sb.append(inName.charAt(i)); -+ Utils.log.warning(sb.toString()); -+ return false; -+ } -+ } -+ return true; - } - - // DEBUG ONLY: Make sure a bunch of cprefs are correct. - private boolean assertValidCPRefs(CPRefBand b) { -- if (b.index == null) return true; -- int limit = b.index.size()+1; -- for (int i = 0; i < b.length(); i++) { -- int v = b.valueAtForDebug(i); -- if (v < 0 || v >= limit) { -- Utils.log.warning("CP ref out of range "+ -- "["+i+"] = "+v+" in "+b); -- return false; -- } -- } -- return true; -+ if (b.index == null) return true; -+ int limit = b.index.size()+1; -+ for (int i = 0; i < b.length(); i++) { -+ int v = b.valueAtForDebug(i); -+ if (v < 0 || v >= limit) { -+ Utils.log.warning("CP ref out of range "+ -+ "["+i+"] = "+v+" in "+b); -+ return false; -+ } -+ } -+ return true; - } - - // DEBUG ONLY: Maybe write a debugging cookie to next output band. - private boolean assertReadyToWriteTo(Band b, OutputStream out) throws IOException { -- Band p = (Band) prevForAssertMap.get(b); -- // Any previous band must be done writing before this one starts. -- if (p != null && phaseCmp(p.phase(), DONE_PHASE) < 0) { -- Utils.log.warning("Previous band not done writing."); -- Utils.log.info(" Previous band: "+p); -- Utils.log.info(" Next band: "+b); -- Thread.dumpStack(); -- assert(verbose > 0); // die unless verbose is true -- } -- String name = b.name; -- if (optDebugBands && !name.startsWith("(")) { -- // Verify synchronization between reader & writer: -- for (int j = 0; j < name.length(); j++) { -- out.write((byte)name.charAt(j)); -- } -- out.write((byte)0); -- } -- return true; -+ Band p = (Band) prevForAssertMap.get(b); -+ // Any previous band must be done writing before this one starts. -+ if (p != null && phaseCmp(p.phase(), DONE_PHASE) < 0) { -+ Utils.log.warning("Previous band not done writing."); -+ Utils.log.info(" Previous band: "+p); -+ Utils.log.info(" Next band: "+b); -+ Thread.dumpStack(); -+ assert(verbose > 0); // die unless verbose is true -+ } -+ String name = b.name; -+ if (optDebugBands && !name.startsWith("(")) { -+ // Verify synchronization between reader & writer: -+ for (int j = 0; j < name.length(); j++) { -+ out.write((byte)name.charAt(j)); -+ } -+ out.write((byte)0); -+ } -+ return true; - } - - protected static boolean testBit(int flags, int bitMask) { -- return (flags & bitMask) != 0; -+ return (flags & bitMask) != 0; - } - protected static int setBit(int flags, int bitMask, boolean z) { -- return z ? (flags | bitMask) : (flags &~ bitMask); -+ return z ? (flags | bitMask) : (flags &~ bitMask); - } - protected static boolean testBit(long flags, long bitMask) { -- return (flags & bitMask) != 0; -+ return (flags & bitMask) != 0; - } - protected static long setBit(long flags, long bitMask, boolean z) { -- return z ? (flags | bitMask) : (flags &~ bitMask); -+ return z ? (flags | bitMask) : (flags &~ bitMask); - } - - - static void printArrayTo(PrintStream ps, int[] values, int start, int end) { -- int len = end-start; -- for (int i = 0; i < len; i++) { -- if (i % 10 == 0) -- ps.println(); -- else -- ps.print(" "); -- ps.print(values[start+i]); -- } -- ps.println(); -+ int len = end-start; -+ for (int i = 0; i < len; i++) { -+ if (i % 10 == 0) -+ ps.println(); -+ else -+ ps.print(" "); -+ ps.print(values[start+i]); -+ } -+ ps.println(); - } - - static void printArrayTo(PrintStream ps, Entry[] cpMap, int start, int end) { -- StringBuffer buf = new StringBuffer(); -- int len = end-start; -- for (int i = 0; i < len; i++) { -- String s = cpMap[start+i].stringValue(); -- buf.setLength(0); -- for (int j = 0; j < s.length(); j++) { -- char ch = s.charAt(j); -- if (!(ch < ' ' || ch > '~' || ch == '\\')) { -- buf.append(ch); -- } else if (ch == '\n') { -- buf.append("\\n"); -- } else if (ch == '\t') { -- buf.append("\\t"); -- } else if (ch == '\r') { -- buf.append("\\r"); -- } else { -- buf.append("\\x"+Integer.toHexString(ch)); -- } -- } -- ps.println(buf); -- } -+ StringBuffer buf = new StringBuffer(); -+ int len = end-start; -+ for (int i = 0; i < len; i++) { -+ String s = cpMap[start+i].stringValue(); -+ buf.setLength(0); -+ for (int j = 0; j < s.length(); j++) { -+ char ch = s.charAt(j); -+ if (!(ch < ' ' || ch > '~' || ch == '\\')) { -+ buf.append(ch); -+ } else if (ch == '\n') { -+ buf.append("\\n"); -+ } else if (ch == '\t') { -+ buf.append("\\t"); -+ } else if (ch == '\r') { -+ buf.append("\\r"); -+ } else { -+ buf.append("\\x"+Integer.toHexString(ch)); -+ } -+ } -+ ps.println(buf); -+ } - } - - - // Utilities for reallocating: - protected static Object[] realloc(Object[] a, int len) { -- java.lang.Class elt = a.getClass().getComponentType(); -- Object[] na = (Object[]) java.lang.reflect.Array.newInstance(elt, len); -- System.arraycopy(a, 0, na, 0, Math.min(a.length, len)); -- return na; -+ java.lang.Class elt = a.getClass().getComponentType(); -+ Object[] na = (Object[]) java.lang.reflect.Array.newInstance(elt, len); -+ System.arraycopy(a, 0, na, 0, Math.min(a.length, len)); -+ return na; - } - protected static Object[] realloc(Object[] a) { -- return realloc(a, Math.max(10, a.length*2)); -+ return realloc(a, Math.max(10, a.length*2)); - } - static private int[] noInts = {}; - protected static int[] realloc(int[] a, int len) { -- if (len == 0) return noInts; -- if (a == null) return new int[len]; -- int[] na = new int[len]; -- System.arraycopy(a, 0, na, 0, Math.min(a.length, len)); -- return na; -+ if (len == 0) return noInts; -+ if (a == null) return new int[len]; -+ int[] na = new int[len]; -+ System.arraycopy(a, 0, na, 0, Math.min(a.length, len)); -+ return na; - } - protected static int[] realloc(int[] a) { -- return realloc(a, Math.max(10, a.length*2)); -+ return realloc(a, Math.max(10, a.length*2)); - } - static private byte[] noBytes = {}; - protected static byte[] realloc(byte[] a, int len) { -- if (len == 0) return noBytes; -- if (a == null) return new byte[len]; -- byte[] na = new byte[len]; -- System.arraycopy(a, 0, na, 0, Math.min(a.length, len)); -- return na; -+ if (len == 0) return noBytes; -+ if (a == null) return new byte[len]; -+ byte[] na = new byte[len]; -+ System.arraycopy(a, 0, na, 0, Math.min(a.length, len)); -+ return na; - } - protected static byte[] realloc(byte[] a) { -- return realloc(a, Math.max(10, a.length*2)); -+ return realloc(a, Math.max(10, a.length*2)); - } - } -+ -+ -diff --git a/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java b/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java ---- jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java -+++ jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -22,7 +22,7 @@ - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -- -+ - package com.sun.java.util.jar.pack; - - import java.io.*; -@@ -37,7 +37,7 @@ class ConstantPool implements Constants - private ConstantPool() {} // do not instantiate - - static int verbose() { -- return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE); -+ return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE); - } - - // Uniquification tables for factory methods: -@@ -53,659 +53,659 @@ class ConstantPool implements Constants - * Also used to back up more complex constant pool entries, like Class. - */ - public static synchronized Utf8Entry getUtf8Entry(String value) { -- Utf8Entry e = (Utf8Entry) utf8Entries.get(value); -- if (e == null) { -- e = new Utf8Entry(value); -- utf8Entries.put(e.stringValue(), e); -- } -- return e; -+ Utf8Entry e = (Utf8Entry) utf8Entries.get(value); -+ if (e == null) { -+ e = new Utf8Entry(value); -+ utf8Entries.put(e.stringValue(), e); -+ } -+ return e; - } - /** Factory for Class constants. */ - public static synchronized ClassEntry getClassEntry(String name) { -- ClassEntry e = (ClassEntry) classEntries.get(name); -- if (e == null) { -- e = (ClassEntry) new ClassEntry(getUtf8Entry(name)); -- assert(name.equals(e.stringValue())); -- classEntries.put(e.stringValue(), e); -- } -- return e; -+ ClassEntry e = (ClassEntry) classEntries.get(name); -+ if (e == null) { -+ e = (ClassEntry) new ClassEntry(getUtf8Entry(name)); -+ assert(name.equals(e.stringValue())); -+ classEntries.put(e.stringValue(), e); -+ } -+ return e; - } - /** Factory for literal constants (String, Integer, etc.). */ - public static synchronized LiteralEntry getLiteralEntry(Comparable value) { -- LiteralEntry e = (LiteralEntry) literalEntries.get(value); -- if (e == null) { -- if (value instanceof String) -- e = new StringEntry(getUtf8Entry((String)value)); -- else -- e = new NumberEntry((Number)value); -- literalEntries.put(value, e); -- } -- return e; -+ LiteralEntry e = (LiteralEntry) literalEntries.get(value); -+ if (e == null) { -+ if (value instanceof String) -+ e = new StringEntry(getUtf8Entry((String)value)); -+ else -+ e = new NumberEntry((Number)value); -+ literalEntries.put(value, e); -+ } -+ return e; - } - /** Factory for literal constants (String, Integer, etc.). */ - public static synchronized StringEntry getStringEntry(String value) { -- return (StringEntry) getLiteralEntry(value); -+ return (StringEntry) getLiteralEntry(value); - } - - /** Factory for signature (type) constants. */ - public static synchronized SignatureEntry getSignatureEntry(String type) { -- SignatureEntry e = (SignatureEntry) signatureEntries.get(type); -- if (e == null) { -- e = new SignatureEntry(type); -- assert(e.stringValue().equals(type)); -- signatureEntries.put(type, e); -- } -- return e; -+ SignatureEntry e = (SignatureEntry) signatureEntries.get(type); -+ if (e == null) { -+ e = new SignatureEntry(type); -+ assert(e.stringValue().equals(type)); -+ signatureEntries.put(type, e); -+ } -+ return e; - } - // Convenience overloading. - public static SignatureEntry getSignatureEntry(Utf8Entry formRef, ClassEntry[] classRefs) { -- return getSignatureEntry(SignatureEntry.stringValueOf(formRef, classRefs)); -+ return getSignatureEntry(SignatureEntry.stringValueOf(formRef, classRefs)); - } - - /** Factory for descriptor (name-and-type) constants. */ - public static synchronized DescriptorEntry getDescriptorEntry(Utf8Entry nameRef, SignatureEntry typeRef) { -- String key = DescriptorEntry.stringValueOf(nameRef, typeRef); -- DescriptorEntry e = (DescriptorEntry) descriptorEntries.get(key); -- if (e == null) { -- e = new DescriptorEntry(nameRef, typeRef); -- assert(e.stringValue().equals(key)) -- : (e.stringValue()+" != "+(key)); -- descriptorEntries.put(key, e); -- } -- return e; -+ String key = DescriptorEntry.stringValueOf(nameRef, typeRef); -+ DescriptorEntry e = (DescriptorEntry) descriptorEntries.get(key); -+ if (e == null) { -+ e = new DescriptorEntry(nameRef, typeRef); -+ assert(e.stringValue().equals(key)) -+ : (e.stringValue()+" != "+(key)); -+ descriptorEntries.put(key, e); -+ } -+ return e; - } - // Convenience overloading. - public static DescriptorEntry getDescriptorEntry(Utf8Entry nameRef, Utf8Entry typeRef) { -- return getDescriptorEntry(nameRef, getSignatureEntry(typeRef.stringValue())); -+ return getDescriptorEntry(nameRef, getSignatureEntry(typeRef.stringValue())); - } - - /** Factory for member reference constants. */ - public static synchronized MemberEntry getMemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) { -- String key = MemberEntry.stringValueOf(tag, classRef, descRef); -- MemberEntry e = (MemberEntry) memberEntries.get(key); -- if (e == null) { -- e = new MemberEntry(tag, classRef, descRef); -- assert(e.stringValue().equals(key)) -- : (e.stringValue()+" != "+(key)); -- memberEntries.put(key, e); -- } -- return e; -+ String key = MemberEntry.stringValueOf(tag, classRef, descRef); -+ MemberEntry e = (MemberEntry) memberEntries.get(key); -+ if (e == null) { -+ e = new MemberEntry(tag, classRef, descRef); -+ assert(e.stringValue().equals(key)) -+ : (e.stringValue()+" != "+(key)); -+ memberEntries.put(key, e); -+ } -+ return e; - } - - - /** Entries in the constant pool. */ - public static abstract - class Entry implements Comparable { -- protected final byte tag; // a CONSTANT_foo code -- protected int valueHash; // cached hashCode -+ protected final byte tag; // a CONSTANT_foo code -+ protected int valueHash; // cached hashCode - -- protected Entry(byte tag) { -- this.tag = tag; -- } -+ protected Entry(byte tag) { -+ this.tag = tag; -+ } - -- public final byte getTag() { -- return tag; -- } -+ public final byte getTag() { -+ return tag; -+ } - -- public Entry getRef(int i) { -- return null; -- } -+ public Entry getRef(int i) { -+ return null; -+ } - -- public boolean sameTagAs(Object o) { -- return (o instanceof Entry) && ((Entry)o).tag == tag; -- } -- public boolean eq(Entry that) { // same reference -- assert(that != null); -- return this == that || this.equals(that); -- } -+ public boolean sameTagAs(Object o) { -+ return (o instanceof Entry) && ((Entry)o).tag == tag; -+ } -+ public boolean eq(Entry that) { // same reference -+ assert(that != null); -+ return this == that || this.equals(that); -+ } - -- // Equality of Entries is value-based. -- public abstract boolean equals(Object o); -- public final int hashCode() { -- if (valueHash == 0) { -- valueHash = computeValueHash(); -- if (valueHash == 0) valueHash = 1; -- } -- return valueHash; -- } -- protected abstract int computeValueHash(); -+ // Equality of Entries is value-based. -+ public abstract boolean equals(Object o); -+ public final int hashCode() { -+ if (valueHash == 0) { -+ valueHash = computeValueHash(); -+ if (valueHash == 0) valueHash = 1; -+ } -+ return valueHash; -+ } -+ protected abstract int computeValueHash(); - -- public abstract int compareTo(Object o); -+ public abstract int compareTo(Object o); - -- protected int superCompareTo(Object o) { -- Entry that = (Entry) o; -+ protected int superCompareTo(Object o) { -+ Entry that = (Entry) o; - -- if (this.tag != that.tag) { -- return TAG_ORDER[this.tag] - TAG_ORDER[that.tag]; -- } -+ if (this.tag != that.tag) { -+ return TAG_ORDER[this.tag] - TAG_ORDER[that.tag]; -+ } - -- return 0; // subclasses must refine this -- } -+ return 0; // subclasses must refine this -+ } - -- public final boolean isDoubleWord() { -- return tag == CONSTANT_Double || tag == CONSTANT_Long; -- } -+ public final boolean isDoubleWord() { -+ return tag == CONSTANT_Double || tag == CONSTANT_Long; -+ } - -- public final boolean tagMatches(int tag) { -- return (this.tag == tag); -- } -+ public final boolean tagMatches(int tag) { -+ return (this.tag == tag); -+ } - -- public String toString() { -- String valuePrint = stringValue(); -- if (verbose() > 4) { -- if (valueHash != 0) -- valuePrint += " hash="+valueHash; -- valuePrint += " id="+System.identityHashCode(this); -- } -- return tagName(tag)+"="+valuePrint; -- } -- public abstract String stringValue(); -+ public String toString() { -+ String valuePrint = stringValue(); -+ if (verbose() > 4) { -+ if (valueHash != 0) -+ valuePrint += " hash="+valueHash; -+ valuePrint += " id="+System.identityHashCode(this); -+ } -+ return tagName(tag)+"="+valuePrint; -+ } -+ public abstract String stringValue(); - } - - public static - class Utf8Entry extends Entry { -- final String value; -+ final String value; - -- Utf8Entry(String value) { -- super(CONSTANT_Utf8); -- this.value = value.intern(); -- hashCode(); // force computation of valueHash -- } -- protected int computeValueHash() { -- return value.hashCode(); -- } -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- // Use reference equality of interned strings: -- return ((Utf8Entry)o).value == value; -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- x = value.compareTo(((Utf8Entry)o).value); -- } -- return x; -- } -- public String stringValue() { -- return value; -- } -+ Utf8Entry(String value) { -+ super(CONSTANT_Utf8); -+ this.value = value.intern(); -+ hashCode(); // force computation of valueHash -+ } -+ protected int computeValueHash() { -+ return value.hashCode(); -+ } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ // Use reference equality of interned strings: -+ return ((Utf8Entry)o).value == value; -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ x = value.compareTo(((Utf8Entry)o).value); -+ } -+ return x; -+ } -+ public String stringValue() { -+ return value; -+ } - } - - static boolean isMemberTag(byte tag) { -- switch (tag) { -- case CONSTANT_Fieldref: -- case CONSTANT_Methodref: -- case CONSTANT_InterfaceMethodref: -- return true; -- } -- return false; -+ switch (tag) { -+ case CONSTANT_Fieldref: -+ case CONSTANT_Methodref: -+ case CONSTANT_InterfaceMethodref: -+ return true; -+ } -+ return false; - } - - static byte numberTagOf(Number value) { -- if (value instanceof Integer) return CONSTANT_Integer; -- if (value instanceof Float) return CONSTANT_Float; -- if (value instanceof Long) return CONSTANT_Long; -- if (value instanceof Double) return CONSTANT_Double; -- throw new RuntimeException("bad literal value "+value); -+ if (value instanceof Integer) return CONSTANT_Integer; -+ if (value instanceof Float) return CONSTANT_Float; -+ if (value instanceof Long) return CONSTANT_Long; -+ if (value instanceof Double) return CONSTANT_Double; -+ throw new RuntimeException("bad literal value "+value); - } - - public static abstract - class LiteralEntry extends Entry { -- protected LiteralEntry(byte tag) { -- super(tag); -- } -+ protected LiteralEntry(byte tag) { -+ super(tag); -+ } - -- public abstract Comparable literalValue(); -+ public abstract Comparable literalValue(); - } - - public static - class NumberEntry extends LiteralEntry { -- final Number value; -- NumberEntry(Number value) { -- super(numberTagOf(value)); -- this.value = value; -- hashCode(); // force computation of valueHash -- } -- protected int computeValueHash() { -- return value.hashCode(); -- } -+ final Number value; -+ NumberEntry(Number value) { -+ super(numberTagOf(value)); -+ this.value = value; -+ hashCode(); // force computation of valueHash -+ } -+ protected int computeValueHash() { -+ return value.hashCode(); -+ } - -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- return (((NumberEntry)o).value).equals(value); -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- x = ((Comparable)value).compareTo(((NumberEntry)o).value); -- } -- return x; -- } -- public Number numberValue() { -- return value; -- } -- public Comparable literalValue() { -- return (Comparable) value; -- } -- public String stringValue() { -- return value.toString(); -- } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ return (((NumberEntry)o).value).equals(value); -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ x = ((Comparable)value).compareTo(((NumberEntry)o).value); -+ } -+ return x; -+ } -+ public Number numberValue() { -+ return value; -+ } -+ public Comparable literalValue() { -+ return (Comparable) value; -+ } -+ public String stringValue() { -+ return value.toString(); -+ } - } - - public static - class StringEntry extends LiteralEntry { -- final Utf8Entry ref; -- public Entry getRef(int i) { return i == 0 ? ref : null; } -+ final Utf8Entry ref; -+ public Entry getRef(int i) { return i == 0 ? ref : null; } - -- StringEntry(Entry ref) { -- super(CONSTANT_String); -- this.ref = (Utf8Entry) ref; -- hashCode(); // force computation of valueHash -- } -- protected int computeValueHash() { -- return ref.hashCode() + tag; -- } -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- return ((StringEntry)o).ref.eq(ref); -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- x = ref.compareTo(((StringEntry)o).ref); -- } -- return x; -- } -- public Comparable literalValue() { -- return ref.stringValue(); -- } -- public String stringValue() { -- return ref.stringValue(); -- } -+ StringEntry(Entry ref) { -+ super(CONSTANT_String); -+ this.ref = (Utf8Entry) ref; -+ hashCode(); // force computation of valueHash -+ } -+ protected int computeValueHash() { -+ return ref.hashCode() + tag; -+ } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ return ((StringEntry)o).ref.eq(ref); -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ x = ref.compareTo(((StringEntry)o).ref); -+ } -+ return x; -+ } -+ public Comparable literalValue() { -+ return ref.stringValue(); -+ } -+ public String stringValue() { -+ return ref.stringValue(); -+ } - } - - public static - class ClassEntry extends Entry { -- final Utf8Entry ref; -- public Entry getRef(int i) { return i == 0 ? ref : null; } -+ final Utf8Entry ref; -+ public Entry getRef(int i) { return i == 0 ? ref : null; } - -- protected int computeValueHash() { -- return ref.hashCode() + tag; -- } -- ClassEntry(Entry ref) { -- super(CONSTANT_Class); -- this.ref = (Utf8Entry) ref; -- hashCode(); // force computation of valueHash -- } -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- return ((ClassEntry)o).ref.eq(ref); -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- x = ref.compareTo(((ClassEntry)o).ref); -- } -- return x; -- } -- public String stringValue() { -- return ref.stringValue(); -- } -+ protected int computeValueHash() { -+ return ref.hashCode() + tag; -+ } -+ ClassEntry(Entry ref) { -+ super(CONSTANT_Class); -+ this.ref = (Utf8Entry) ref; -+ hashCode(); // force computation of valueHash -+ } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ return ((ClassEntry)o).ref.eq(ref); -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ x = ref.compareTo(((ClassEntry)o).ref); -+ } -+ return x; -+ } -+ public String stringValue() { -+ return ref.stringValue(); -+ } - } - - public static - class DescriptorEntry extends Entry { -- final Utf8Entry nameRef; -- final SignatureEntry typeRef; -- public Entry getRef(int i) { -- if (i == 0) return nameRef; -- if (i == 1) return typeRef; -- return null; -- } -- DescriptorEntry(Entry nameRef, Entry typeRef) { -- super(CONSTANT_NameandType); -- if (typeRef instanceof Utf8Entry) { -- typeRef = getSignatureEntry(typeRef.stringValue()); -- } -- this.nameRef = (Utf8Entry) nameRef; -- this.typeRef = (SignatureEntry) typeRef; -- hashCode(); // force computation of valueHash -- } -- protected int computeValueHash() { -- int hc2 = typeRef.hashCode(); -- return (nameRef.hashCode() + (hc2 << 8)) ^ hc2; -- } -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- DescriptorEntry that = (DescriptorEntry)o; -- return this.nameRef.eq(that.nameRef) -- && this.typeRef.eq(that.typeRef); -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- DescriptorEntry that = (DescriptorEntry)o; -- // Primary key is typeRef, not nameRef. -- x = this.typeRef.compareTo(that.typeRef); -- if (x == 0) -- x = this.nameRef.compareTo(that.nameRef); -- } -- return x; -- } -- public String stringValue() { -- return stringValueOf(nameRef, typeRef); -- } -- static -- String stringValueOf(Entry nameRef, Entry typeRef) { -- return typeRef.stringValue()+","+nameRef.stringValue(); -- } -+ final Utf8Entry nameRef; -+ final SignatureEntry typeRef; -+ public Entry getRef(int i) { -+ if (i == 0) return nameRef; -+ if (i == 1) return typeRef; -+ return null; -+ } -+ DescriptorEntry(Entry nameRef, Entry typeRef) { -+ super(CONSTANT_NameandType); -+ if (typeRef instanceof Utf8Entry) { -+ typeRef = getSignatureEntry(typeRef.stringValue()); -+ } -+ this.nameRef = (Utf8Entry) nameRef; -+ this.typeRef = (SignatureEntry) typeRef; -+ hashCode(); // force computation of valueHash -+ } -+ protected int computeValueHash() { -+ int hc2 = typeRef.hashCode(); -+ return (nameRef.hashCode() + (hc2 << 8)) ^ hc2; -+ } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ DescriptorEntry that = (DescriptorEntry)o; -+ return this.nameRef.eq(that.nameRef) -+ && this.typeRef.eq(that.typeRef); -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ DescriptorEntry that = (DescriptorEntry)o; -+ // Primary key is typeRef, not nameRef. -+ x = this.typeRef.compareTo(that.typeRef); -+ if (x == 0) -+ x = this.nameRef.compareTo(that.nameRef); -+ } -+ return x; -+ } -+ public String stringValue() { -+ return stringValueOf(nameRef, typeRef); -+ } -+ static -+ String stringValueOf(Entry nameRef, Entry typeRef) { -+ return typeRef.stringValue()+","+nameRef.stringValue(); -+ } - -- public String prettyString() { -- return nameRef.stringValue()+typeRef.prettyString(); -- } -+ public String prettyString() { -+ return nameRef.stringValue()+typeRef.prettyString(); -+ } - -- public boolean isMethod() { -- return typeRef.isMethod(); -- } -+ public boolean isMethod() { -+ return typeRef.isMethod(); -+ } - -- public byte getLiteralTag() { -- return typeRef.getLiteralTag(); -- } -+ public byte getLiteralTag() { -+ return typeRef.getLiteralTag(); -+ } - } - - public static - class MemberEntry extends Entry { -- final ClassEntry classRef; -- final DescriptorEntry descRef; -- public Entry getRef(int i) { -- if (i == 0) return classRef; -- if (i == 1) return descRef; -- return null; -- } -- protected int computeValueHash() { -- int hc2 = descRef.hashCode(); -- return (classRef.hashCode() + (hc2 << 8)) ^ hc2; -- } -+ final ClassEntry classRef; -+ final DescriptorEntry descRef; -+ public Entry getRef(int i) { -+ if (i == 0) return classRef; -+ if (i == 1) return descRef; -+ return null; -+ } -+ protected int computeValueHash() { -+ int hc2 = descRef.hashCode(); -+ return (classRef.hashCode() + (hc2 << 8)) ^ hc2; -+ } - -- MemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) { -- super(tag); -- assert(isMemberTag(tag)); -- this.classRef = classRef; -- this.descRef = descRef; -- hashCode(); // force computation of valueHash -- } -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- MemberEntry that = (MemberEntry)o; -- return this.classRef.eq(that.classRef) -- && this.descRef.eq(that.descRef); -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- MemberEntry that = (MemberEntry)o; -- // Primary key is classRef. -- x = this.classRef.compareTo(that.classRef); -- if (x == 0) -- x = this.descRef.compareTo(that.descRef); -- } -- return x; -- } -- public String stringValue() { -- return stringValueOf(tag, classRef, descRef); -- } -- static -- String stringValueOf(byte tag, ClassEntry classRef, DescriptorEntry descRef) { -- assert(isMemberTag(tag)); -- String pfx; -- switch (tag) { -- case CONSTANT_Fieldref: pfx = "Field:"; break; -- case CONSTANT_Methodref: pfx = "Method:"; break; -- case CONSTANT_InterfaceMethodref: pfx = "IMethod:"; break; -- default: pfx = tag+"???"; break; -- } -- return pfx+classRef.stringValue()+","+descRef.stringValue(); -- } -+ MemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) { -+ super(tag); -+ assert(isMemberTag(tag)); -+ this.classRef = classRef; -+ this.descRef = descRef; -+ hashCode(); // force computation of valueHash -+ } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ MemberEntry that = (MemberEntry)o; -+ return this.classRef.eq(that.classRef) -+ && this.descRef.eq(that.descRef); -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ MemberEntry that = (MemberEntry)o; -+ // Primary key is classRef. -+ x = this.classRef.compareTo(that.classRef); -+ if (x == 0) -+ x = this.descRef.compareTo(that.descRef); -+ } -+ return x; -+ } -+ public String stringValue() { -+ return stringValueOf(tag, classRef, descRef); -+ } -+ static -+ String stringValueOf(byte tag, ClassEntry classRef, DescriptorEntry descRef) { -+ assert(isMemberTag(tag)); -+ String pfx; -+ switch (tag) { -+ case CONSTANT_Fieldref: pfx = "Field:"; break; -+ case CONSTANT_Methodref: pfx = "Method:"; break; -+ case CONSTANT_InterfaceMethodref: pfx = "IMethod:"; break; -+ default: pfx = tag+"???"; break; -+ } -+ return pfx+classRef.stringValue()+","+descRef.stringValue(); -+ } - -- public boolean isMethod() { -- return descRef.isMethod(); -- } -+ public boolean isMethod() { -+ return descRef.isMethod(); -+ } - } - - public static - class SignatureEntry extends Entry { -- final Utf8Entry formRef; -- final ClassEntry[] classRefs; -- String value; -- Utf8Entry asUtf8Entry; -- public Entry getRef(int i) { -- if (i == 0) return formRef; -- return i-1 < classRefs.length ? classRefs[i-1] : null; -- } -- SignatureEntry(String value) { -- super(CONSTANT_Signature); -- value = value.intern(); // always do this -- this.value = value; -- String[] parts = structureSignature(value); -- formRef = getUtf8Entry(parts[0]); -- classRefs = new ClassEntry[parts.length-1]; -- for (int i = 1; i < parts.length; i++) -- classRefs[i-1] = getClassEntry(parts[i]); -- hashCode(); // force computation of valueHash -- } -- protected int computeValueHash() { -- stringValue(); // force computation of value -- return value.hashCode() + tag; -- } -+ final Utf8Entry formRef; -+ final ClassEntry[] classRefs; -+ String value; -+ Utf8Entry asUtf8Entry; -+ public Entry getRef(int i) { -+ if (i == 0) return formRef; -+ return i-1 < classRefs.length ? classRefs[i-1] : null; -+ } -+ SignatureEntry(String value) { -+ super(CONSTANT_Signature); -+ value = value.intern(); // always do this -+ this.value = value; -+ String[] parts = structureSignature(value); -+ formRef = getUtf8Entry(parts[0]); -+ classRefs = new ClassEntry[parts.length-1]; -+ for (int i = 1; i < parts.length; i++) -+ classRefs[i-1] = getClassEntry(parts[i]); -+ hashCode(); // force computation of valueHash -+ } -+ protected int computeValueHash() { -+ stringValue(); // force computation of value -+ return value.hashCode() + tag; -+ } - -- public Utf8Entry asUtf8Entry() { -- if (asUtf8Entry == null) { -- asUtf8Entry = getUtf8Entry(stringValue()); -- } -- return asUtf8Entry; -- } -+ public Utf8Entry asUtf8Entry() { -+ if (asUtf8Entry == null) { -+ asUtf8Entry = getUtf8Entry(stringValue()); -+ } -+ return asUtf8Entry; -+ } - -- public boolean equals(Object o) { -- if (!sameTagAs(o)) return false; -- return ((SignatureEntry)o).value == value; -- } -- public int compareTo(Object o) { -- int x = superCompareTo(o); -- if (x == 0) { -- SignatureEntry that = (SignatureEntry)o; -- x = compareSignatures(this.value, that.value); -- } -- return x; -- } -- public String stringValue() { -- if (value == null) { -- value = stringValueOf(formRef, classRefs); -- } -- return value; -- } -- static -- String stringValueOf(Utf8Entry formRef, ClassEntry[] classRefs) { -- String[] parts = new String[1+classRefs.length]; -- parts[0] = formRef.stringValue(); -- for (int i = 1; i < parts.length; i++) -- parts[i] = classRefs[i-1].stringValue(); -- return flattenSignature(parts).intern(); -- } -+ public boolean equals(Object o) { -+ if (!sameTagAs(o)) return false; -+ return ((SignatureEntry)o).value == value; -+ } -+ public int compareTo(Object o) { -+ int x = superCompareTo(o); -+ if (x == 0) { -+ SignatureEntry that = (SignatureEntry)o; -+ x = compareSignatures(this.value, that.value); -+ } -+ return x; -+ } -+ public String stringValue() { -+ if (value == null) { -+ value = stringValueOf(formRef, classRefs); -+ } -+ return value; -+ } -+ static -+ String stringValueOf(Utf8Entry formRef, ClassEntry[] classRefs) { -+ String[] parts = new String[1+classRefs.length]; -+ parts[0] = formRef.stringValue(); -+ for (int i = 1; i < parts.length; i++) -+ parts[i] = classRefs[i-1].stringValue(); -+ return flattenSignature(parts).intern(); -+ } - -- public int computeSize(boolean countDoublesTwice) { -- String form = formRef.stringValue(); -- int min = 0; -- int max = 1; -- if (isMethod()) { -- min = 1; -- max = form.indexOf(')'); -- } -- int size = 0; -- for (int i = min; i < max; i++) { -- switch (form.charAt(i)) { -- case 'D': -- case 'J': -- if (countDoublesTwice) size++; -- break; -- case '[': -- // Skip rest of array info. -- while (form.charAt(i) == '[') ++i; -- break; -- case ';': -- continue; -- default: -- assert(0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i))); -- break; -- } -- size++; -- } -- return size; -- } -- public boolean isMethod() { -- return formRef.stringValue().charAt(0) == '('; -- } -- public byte getLiteralTag() { -- switch (formRef.stringValue().charAt(0)) { -- case 'L': return CONSTANT_String; -- case 'I': return CONSTANT_Integer; -- case 'J': return CONSTANT_Long; -- case 'F': return CONSTANT_Float; -- case 'D': return CONSTANT_Double; -- case 'B': case 'S': case 'C': case 'Z': -- return CONSTANT_Integer; -- } -- assert(false); -- return CONSTANT_None; -- } -- public String prettyString() { -- String s; -- if (isMethod()) { -- s = formRef.stringValue(); -- s = s.substring(0, 1+s.indexOf(')')); -- } else { -- s = "/" + formRef.stringValue(); -- } -- int i; -- while ((i = s.indexOf(';')) >= 0) -- s = s.substring(0,i) + s.substring(i+1); -- return s; -- } -+ public int computeSize(boolean countDoublesTwice) { -+ String form = formRef.stringValue(); -+ int min = 0; -+ int max = 1; -+ if (isMethod()) { -+ min = 1; -+ max = form.indexOf(')'); -+ } -+ int size = 0; -+ for (int i = min; i < max; i++) { -+ switch (form.charAt(i)) { -+ case 'D': -+ case 'J': -+ if (countDoublesTwice) size++; -+ break; -+ case '[': -+ // Skip rest of array info. -+ while (form.charAt(i) == '[') ++i; -+ break; -+ case ';': -+ continue; -+ default: -+ assert(0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i))); -+ break; -+ } -+ size++; -+ } -+ return size; -+ } -+ public boolean isMethod() { -+ return formRef.stringValue().charAt(0) == '('; -+ } -+ public byte getLiteralTag() { -+ switch (formRef.stringValue().charAt(0)) { -+ case 'L': return CONSTANT_String; -+ case 'I': return CONSTANT_Integer; -+ case 'J': return CONSTANT_Long; -+ case 'F': return CONSTANT_Float; -+ case 'D': return CONSTANT_Double; -+ case 'B': case 'S': case 'C': case 'Z': -+ return CONSTANT_Integer; -+ } -+ assert(false); -+ return CONSTANT_None; -+ } -+ public String prettyString() { -+ String s; -+ if (isMethod()) { -+ s = formRef.stringValue(); -+ s = s.substring(0, 1+s.indexOf(')')); -+ } else { -+ s = "/" + formRef.stringValue(); -+ } -+ int i; -+ while ((i = s.indexOf(';')) >= 0) -+ s = s.substring(0,i) + s.substring(i+1); -+ return s; -+ } - } - - static int compareSignatures(String s1, String s2) { -- return compareSignatures(s1, s2, null, null); -+ return compareSignatures(s1, s2, null, null); - } - static int compareSignatures(String s1, String s2, String[] p1, String[] p2) { -- final int S1_COMES_FIRST = -1; -- final int S2_COMES_FIRST = +1; -- char c1 = s1.charAt(0); -- char c2 = s2.charAt(0); -- // fields before methods (because there are fewer of them) -- if (c1 != '(' && c2 == '(') return S1_COMES_FIRST; -- if (c2 != '(' && c1 == '(') return S2_COMES_FIRST; -- if (p1 == null) p1 = structureSignature(s1); -- if (p2 == null) p2 = structureSignature(s2); -- /* -- // non-classes before classes (because there are fewer of them) -- if (p1.length == 1 && p2.length > 1) return S1_COMES_FIRST; -- if (p2.length == 1 && p1.length > 1) return S2_COMES_FIRST; -- // all else being equal, use the same comparison as for Utf8 strings -- return s1.compareTo(s2); -- */ -- if (p1.length != p2.length) return p1.length - p2.length; -- int length = p1.length; -- for (int i = length; --i >= 0; ) { -- int res = p1[i].compareTo(p2[i]); -- if (res != 0) return res; -- } -- assert(s1.equals(s2)); -- return 0; -+ final int S1_COMES_FIRST = -1; -+ final int S2_COMES_FIRST = +1; -+ char c1 = s1.charAt(0); -+ char c2 = s2.charAt(0); -+ // fields before methods (because there are fewer of them) -+ if (c1 != '(' && c2 == '(') return S1_COMES_FIRST; -+ if (c2 != '(' && c1 == '(') return S2_COMES_FIRST; -+ if (p1 == null) p1 = structureSignature(s1); -+ if (p2 == null) p2 = structureSignature(s2); -+ /* -+ // non-classes before classes (because there are fewer of them) -+ if (p1.length == 1 && p2.length > 1) return S1_COMES_FIRST; -+ if (p2.length == 1 && p1.length > 1) return S2_COMES_FIRST; -+ // all else being equal, use the same comparison as for Utf8 strings -+ return s1.compareTo(s2); -+ */ -+ if (p1.length != p2.length) return p1.length - p2.length; -+ int length = p1.length; -+ for (int i = length; --i >= 0; ) { -+ int res = p1[i].compareTo(p2[i]); -+ if (res != 0) return res; -+ } -+ assert(s1.equals(s2)); -+ return 0; - } - - static int countClassParts(Utf8Entry formRef) { -- int num = 0; -- String s = formRef.stringValue(); -- for (int i = 0; i < s.length(); i++) { -- if (s.charAt(i) == 'L') ++num; -- } -- return num; -+ int num = 0; -+ String s = formRef.stringValue(); -+ for (int i = 0; i < s.length(); i++) { -+ if (s.charAt(i) == 'L') ++num; -+ } -+ return num; - } - - static String flattenSignature(String[] parts) { -- String form = parts[0]; -- if (parts.length == 1) return form; -- int len = form.length(); -- for (int i = 1; i < parts.length; i++) { -- len += parts[i].length(); -- } -- char[] sig = new char[len]; -- int j = 0; -- int k = 1; -- for (int i = 0; i < form.length(); i++) { -- char ch = form.charAt(i); -- sig[j++] = ch; -- if (ch == 'L') { -- String cls = parts[k++]; -- cls.getChars(0, cls.length(), sig, j); -- j += cls.length(); -- //sig[j++] = ';'; -- } -- } -- assert(j == len); -- assert(k == parts.length); -- return new String(sig); -+ String form = parts[0]; -+ if (parts.length == 1) return form; -+ int len = form.length(); -+ for (int i = 1; i < parts.length; i++) { -+ len += parts[i].length(); -+ } -+ char[] sig = new char[len]; -+ int j = 0; -+ int k = 1; -+ for (int i = 0; i < form.length(); i++) { -+ char ch = form.charAt(i); -+ sig[j++] = ch; -+ if (ch == 'L') { -+ String cls = parts[k++]; -+ cls.getChars(0, cls.length(), sig, j); -+ j += cls.length(); -+ //sig[j++] = ';'; -+ } -+ } -+ assert(j == len); -+ assert(k == parts.length); -+ return new String(sig); - } - - static private int skipClassNameChars(String sig, int i) { -- int len = sig.length(); -- for (; i < len; i++) { -- char ch = sig.charAt(i); -- if (ch <= ' ') break; -- if (ch >= ';' && ch <= '@') break; -- } -- return i; -+ int len = sig.length(); -+ for (; i < len; i++) { -+ char ch = sig.charAt(i); -+ if (ch <= ' ') break; -+ if (ch >= ';' && ch <= '@') break; -+ } -+ return i; - } - - static String[] structureSignature(String sig) { -- sig = sig.intern(); -+ sig = sig.intern(); - -- int formLen = 0; -- int nparts = 1; -- for (int i = 0; i < sig.length(); i++) { -- char ch = sig.charAt(i); -- formLen++; -- if (ch == 'L') { -- nparts++; -- int i2 = skipClassNameChars(sig, i+1); -- i = i2-1; // keep the semicolon in the form -- int i3 = sig.indexOf('<', i+1); -- if (i3 > 0 && i3 < i2) -- i = i3-1; -- } -- } -- char[] form = new char[formLen]; -- if (nparts == 1) { -- String[] parts = { sig }; -- return parts; -- } -- String[] parts = new String[nparts]; -- int j = 0; -- int k = 1; -- for (int i = 0; i < sig.length(); i++) { -- char ch = sig.charAt(i); -- form[j++] = ch; -- if (ch == 'L') { -- int i2 = skipClassNameChars(sig, i+1); -- parts[k++] = sig.substring(i+1, i2); -- i = i2; -- --i; // keep the semicolon in the form -- } -- } -- assert(j == formLen); -- assert(k == parts.length); -- parts[0] = new String(form); -- //assert(flattenSignature(parts).equals(sig)); -- return parts; -+ int formLen = 0; -+ int nparts = 1; -+ for (int i = 0; i < sig.length(); i++) { -+ char ch = sig.charAt(i); -+ formLen++; -+ if (ch == 'L') { -+ nparts++; -+ int i2 = skipClassNameChars(sig, i+1); -+ i = i2-1; // keep the semicolon in the form -+ int i3 = sig.indexOf('<', i+1); -+ if (i3 > 0 && i3 < i2) -+ i = i3-1; -+ } -+ } -+ char[] form = new char[formLen]; -+ if (nparts == 1) { -+ String[] parts = { sig }; -+ return parts; -+ } -+ String[] parts = new String[nparts]; -+ int j = 0; -+ int k = 1; -+ for (int i = 0; i < sig.length(); i++) { -+ char ch = sig.charAt(i); -+ form[j++] = ch; -+ if (ch == 'L') { -+ int i2 = skipClassNameChars(sig, i+1); -+ parts[k++] = sig.substring(i+1, i2); -+ i = i2; -+ --i; // keep the semicolon in the form -+ } -+ } -+ assert(j == formLen); -+ assert(k == parts.length); -+ parts[0] = new String(form); -+ //assert(flattenSignature(parts).equals(sig)); -+ return parts; - } - - // Handy constants: -@@ -715,182 +715,182 @@ class ConstantPool implements Constants - /** An Index is a mapping between CP entries and small integers. */ - public static - class Index extends AbstractList { -- protected String debugName; -- protected Entry[] cpMap; -- protected boolean flattenSigs; -- protected Entry[] getMap() { -- return cpMap; -- } -- protected Index(String debugName) { -- this.debugName = debugName; -- } -- protected Index(String debugName, Entry[] cpMap) { -- this(debugName); -- setMap(cpMap); -- } -- protected void setMap(Entry[] cpMap) { -- clearIndex(); -- this.cpMap = cpMap; -- } -- protected Index(String debugName, Collection cpMapList) { -- this(debugName); -- setMap(cpMapList); -- } -- protected void setMap(Collection cpMapList) { -- cpMap = new Entry[cpMapList.size()]; -- cpMapList.toArray(cpMap); -- setMap(cpMap); -- } -- public int size() { -- return cpMap.length; -- } -- public Object get(int i) { -- return cpMap[i]; -- } -- public Entry getEntry(int i) { -- // same as get(), with covariant return type -- return cpMap[i]; -- } -+ protected String debugName; -+ protected Entry[] cpMap; -+ protected boolean flattenSigs; -+ protected Entry[] getMap() { -+ return cpMap; -+ } -+ protected Index(String debugName) { -+ this.debugName = debugName; -+ } -+ protected Index(String debugName, Entry[] cpMap) { -+ this(debugName); -+ setMap(cpMap); -+ } -+ protected void setMap(Entry[] cpMap) { -+ clearIndex(); -+ this.cpMap = cpMap; -+ } -+ protected Index(String debugName, Collection cpMapList) { -+ this(debugName); -+ setMap(cpMapList); -+ } -+ protected void setMap(Collection cpMapList) { -+ cpMap = new Entry[cpMapList.size()]; -+ cpMapList.toArray(cpMap); -+ setMap(cpMap); -+ } -+ public int size() { -+ return cpMap.length; -+ } -+ public Object get(int i) { -+ return cpMap[i]; -+ } -+ public Entry getEntry(int i) { -+ // same as get(), with covariant return type -+ return cpMap[i]; -+ } - -- // Find index of e in cpMap, or return -1 if none. -- // -- // As a special hack, if flattenSigs, signatures are -- // treated as equivalent entries of cpMap. This is wrong -- // fron a Collection point of view, because contains() -- // reports true for signatures, but the iterator() -- // never produces them! -- private int findIndexOf(Entry e) { -- if (indexKey == null) initializeIndex(); -- int probe = findIndexLocation(e); -- if (indexKey[probe] != e) { -- if (flattenSigs && e.tag == CONSTANT_Signature) { -- SignatureEntry se = (SignatureEntry) e; -- return findIndexOf(se.asUtf8Entry()); -- } -- return -1; -- } -- int index = indexValue[probe]; -- assert(e.equals(cpMap[index])); -- return index; -- } -- public boolean contains(Entry e) { -- return findIndexOf(e) >= 0; -- } -- // Find index of e in cpMap. Should not return -1. -- public int indexOf(Entry e) { -- int index = findIndexOf(e); -- if (index < 0 && verbose() > 0) { -- System.out.println("not found: "+e); -- System.out.println(" in: "+this.dumpString()); -- Thread.dumpStack(); -- } -- assert(index >= 0); -- return index; -- } -- public boolean contains(Object e) { -- return findIndexOf((Entry)e) >= 0; -- } -- public int indexOf(Object e) { -- return findIndexOf((Entry)e); -- } -- public int lastIndexOf(Object e) { -- return indexOf(e); -- } -+ // Find index of e in cpMap, or return -1 if none. -+ // -+ // As a special hack, if flattenSigs, signatures are -+ // treated as equivalent entries of cpMap. This is wrong -+ // fron a Collection point of view, because contains() -+ // reports true for signatures, but the iterator() -+ // never produces them! -+ private int findIndexOf(Entry e) { -+ if (indexKey == null) initializeIndex(); -+ int probe = findIndexLocation(e); -+ if (indexKey[probe] != e) { -+ if (flattenSigs && e.tag == CONSTANT_Signature) { -+ SignatureEntry se = (SignatureEntry) e; -+ return findIndexOf(se.asUtf8Entry()); -+ } -+ return -1; -+ } -+ int index = indexValue[probe]; -+ assert(e.equals(cpMap[index])); -+ return index; -+ } -+ public boolean contains(Entry e) { -+ return findIndexOf(e) >= 0; -+ } -+ // Find index of e in cpMap. Should not return -1. -+ public int indexOf(Entry e) { -+ int index = findIndexOf(e); -+ if (index < 0 && verbose() > 0) { -+ System.out.println("not found: "+e); -+ System.out.println(" in: "+this.dumpString()); -+ Thread.dumpStack(); -+ } -+ assert(index >= 0); -+ return index; -+ } -+ public boolean contains(Object e) { -+ return findIndexOf((Entry)e) >= 0; -+ } -+ public int indexOf(Object e) { -+ return findIndexOf((Entry)e); -+ } -+ public int lastIndexOf(Object e) { -+ return indexOf(e); -+ } - -- public boolean assertIsSorted() { -- for (int i = 1; i < cpMap.length; i++) { -- if (cpMap[i-1].compareTo(cpMap[i]) > 0) { -- System.out.println("Not sorted at "+(i-1)+"/"+i+": "+this.dumpString()); -- return false; -- } -- } -- return true; -- } -+ public boolean assertIsSorted() { -+ for (int i = 1; i < cpMap.length; i++) { -+ if (cpMap[i-1].compareTo(cpMap[i]) > 0) { -+ System.out.println("Not sorted at "+(i-1)+"/"+i+": "+this.dumpString()); -+ return false; -+ } -+ } -+ return true; -+ } - -- // internal hash table -- protected Entry[] indexKey; -- protected int[] indexValue; -- protected void clearIndex() { -- indexKey = null; -- indexValue = null; -- } -- private int findIndexLocation(Entry e) { -- int size = indexKey.length; -- int hash = e.hashCode(); -- int probe = hash & (size - 1); -- int stride = ((hash >>> 8) | 1) & (size - 1); -- for (;;) { -- Entry e1 = indexKey[probe]; -- if (e1 == e || e1 == null) -- return probe; -- probe += stride; -- if (probe >= size) probe -= size; -- } -- } -- private void initializeIndex() { -- if (verbose() > 2) -- System.out.println("initialize Index "+debugName+" ["+size()+"]"); -- int hsize0 = (int)((cpMap.length + 10) * 1.5); -- int hsize = 1; -- while (hsize < hsize0) hsize <<= 1; -- indexKey = new Entry[hsize]; -- indexValue = new int[hsize]; -- for (int i = 0; i < cpMap.length; i++) { -- Entry e = cpMap[i]; -- if (e == null) continue; -- int probe = findIndexLocation(e); -- assert(indexKey[probe] == null); // e has unique index -- indexKey[probe] = e; -- indexValue[probe] = i; -- } -- } -- public Object[] toArray(Object[] a) { -- int sz = size(); -- if (a.length < sz) return super.toArray(a); -- System.arraycopy(cpMap, 0, a, 0, sz); -- if (a.length > sz) a[sz] = null; -- return a; -- } -- public Object[] toArray() { -- return toArray(new Entry[size()]); -- } -- public Object clone() { -- return new Index(debugName, (Entry[]) cpMap.clone()); -- } -- public String toString() { -- return "Index "+debugName+" ["+size()+"]"; -- } -- public String dumpString() { -- String s = toString(); -- s += " {\n"; -- for (int i = 0; i < cpMap.length; i++) { -- s += " "+i+": "+cpMap[i]+"\n"; -- } -- s += "}"; -- return s; -- } -+ // internal hash table -+ protected Entry[] indexKey; -+ protected int[] indexValue; -+ protected void clearIndex() { -+ indexKey = null; -+ indexValue = null; -+ } -+ private int findIndexLocation(Entry e) { -+ int size = indexKey.length; -+ int hash = e.hashCode(); -+ int probe = hash & (size - 1); -+ int stride = ((hash >>> 8) | 1) & (size - 1); -+ for (;;) { -+ Entry e1 = indexKey[probe]; -+ if (e1 == e || e1 == null) -+ return probe; -+ probe += stride; -+ if (probe >= size) probe -= size; -+ } -+ } -+ private void initializeIndex() { -+ if (verbose() > 2) -+ System.out.println("initialize Index "+debugName+" ["+size()+"]"); -+ int hsize0 = (int)((cpMap.length + 10) * 1.5); -+ int hsize = 1; -+ while (hsize < hsize0) hsize <<= 1; -+ indexKey = new Entry[hsize]; -+ indexValue = new int[hsize]; -+ for (int i = 0; i < cpMap.length; i++) { -+ Entry e = cpMap[i]; -+ if (e == null) continue; -+ int probe = findIndexLocation(e); -+ assert(indexKey[probe] == null); // e has unique index -+ indexKey[probe] = e; -+ indexValue[probe] = i; -+ } -+ } -+ public Object[] toArray(Object[] a) { -+ int sz = size(); -+ if (a.length < sz) return super.toArray(a); -+ System.arraycopy(cpMap, 0, a, 0, sz); -+ if (a.length > sz) a[sz] = null; -+ return a; -+ } -+ public Object[] toArray() { -+ return toArray(new Entry[size()]); -+ } -+ public Object clone() { -+ return new Index(debugName, (Entry[]) cpMap.clone()); -+ } -+ public String toString() { -+ return "Index "+debugName+" ["+size()+"]"; -+ } -+ public String dumpString() { -+ String s = toString(); -+ s += " {\n"; -+ for (int i = 0; i < cpMap.length; i++) { -+ s += " "+i+": "+cpMap[i]+"\n"; -+ } -+ s += "}"; -+ return s; -+ } - } - - // Index methods. - - public static - Index makeIndex(String debugName, Entry[] cpMap) { -- return new Index(debugName, cpMap); -+ return new Index(debugName, cpMap); - } - - public static - Index makeIndex(String debugName, Collection cpMapList) { -- return new Index(debugName, cpMapList); -+ return new Index(debugName, cpMapList); - } - - /** Sort this index (destructively) into canonical order. */ - public static - void sort(Index ix) { -- // %%% Should move this into class Index. -- ix.clearIndex(); -- Arrays.sort(ix.cpMap); -- if (verbose() > 2) -- System.out.println("sorted "+ix.dumpString()); -+ // %%% Should move this into class Index. -+ ix.clearIndex(); -+ Arrays.sort(ix.cpMap); -+ if (verbose() > 2) -+ System.out.println("sorted "+ix.dumpString()); - } - - /** Return a set of indexes partitioning these entries. -@@ -900,210 +900,212 @@ class ConstantPool implements Constants - */ - public static - Index[] partition(Index ix, int[] keys) { -- // %%% Should move this into class Index. -- ArrayList parts = new ArrayList(); -- Entry[] cpMap = ix.cpMap; -- assert(keys.length == cpMap.length); -- for (int i = 0; i < keys.length; i++) { -- int key = keys[i]; -- if (key < 0) continue; -- while (key >= parts.size()) parts.add(null); -- ArrayList part = (ArrayList) parts.get(key); -- if (part == null) { -- parts.set(key, part = new ArrayList()); -- } -- part.add(cpMap[i]); -- } -- Index[] indexes = new Index[parts.size()]; -- for (int key = 0; key < indexes.length; key++) { -- ArrayList part = (ArrayList) parts.get(key); -- if (part == null) continue; -- indexes[key] = new Index(ix.debugName+"/part#"+key, part); -- assert(indexes[key].indexOf(part.get(0)) == 0); -- } -- return indexes; -+ // %%% Should move this into class Index. -+ ArrayList parts = new ArrayList(); -+ Entry[] cpMap = ix.cpMap; -+ assert(keys.length == cpMap.length); -+ for (int i = 0; i < keys.length; i++) { -+ int key = keys[i]; -+ if (key < 0) continue; -+ while (key >= parts.size()) parts.add(null); -+ ArrayList part = (ArrayList) parts.get(key); -+ if (part == null) { -+ parts.set(key, part = new ArrayList()); -+ } -+ part.add(cpMap[i]); -+ } -+ Index[] indexes = new Index[parts.size()]; -+ for (int key = 0; key < indexes.length; key++) { -+ ArrayList part = (ArrayList) parts.get(key); -+ if (part == null) continue; -+ indexes[key] = new Index(ix.debugName+"/part#"+key, part); -+ assert(indexes[key].indexOf(part.get(0)) == 0); -+ } -+ return indexes; - } - public static - Index[] partitionByTag(Index ix) { -- // Partition by tag. -- Entry[] cpMap = ix.cpMap; -- int[] keys = new int[cpMap.length]; -- for (int i = 0; i < keys.length; i++) { -- Entry e = cpMap[i]; -- keys[i] = (e == null)? -1: e.tag; -- } -- Index[] byTag = partition(ix, keys); -- for (int tag = 0; tag < byTag.length; tag++) { -- if (byTag[tag] == null) continue; -- byTag[tag].debugName = tagName(tag); -- } -- if (byTag.length < CONSTANT_Limit) { -- Index[] longer = new Index[CONSTANT_Limit]; -- System.arraycopy(byTag, 0, longer, 0, byTag.length); -- byTag = longer; -- } -- return byTag; -+ // Partition by tag. -+ Entry[] cpMap = ix.cpMap; -+ int[] keys = new int[cpMap.length]; -+ for (int i = 0; i < keys.length; i++) { -+ Entry e = cpMap[i]; -+ keys[i] = (e == null)? -1: e.tag; -+ } -+ Index[] byTag = partition(ix, keys); -+ for (int tag = 0; tag < byTag.length; tag++) { -+ if (byTag[tag] == null) continue; -+ byTag[tag].debugName = tagName(tag); -+ } -+ if (byTag.length < CONSTANT_Limit) { -+ Index[] longer = new Index[CONSTANT_Limit]; -+ System.arraycopy(byTag, 0, longer, 0, byTag.length); -+ byTag = longer; -+ } -+ return byTag; - } - - /** Coherent group of constant pool indexes. */ - public static - class IndexGroup { -- private Index indexUntyped; -- private Index[] indexByTag = new Index[CONSTANT_Limit]; -- private int[] untypedFirstIndexByTag; -- private int totalSize; -- private Index[][] indexByTagAndClass; -+ private Index indexUntyped; -+ private Index[] indexByTag = new Index[CONSTANT_Limit]; -+ private int[] untypedFirstIndexByTag; -+ private int totalSize; -+ private Index[][] indexByTagAndClass; - -- /** Index of all CP entries of all types, in definition order. */ -- public Index getUntypedIndex() { -- if (indexUntyped == null) { -- untypedIndexOf(null); // warm up untypedFirstIndexByTag -- Entry[] cpMap = new Entry[totalSize]; -- for (int tag = 0; tag < indexByTag.length; tag++) { -- Index ix = indexByTag[tag]; -- if (ix == null) continue; -- int ixLen = ix.cpMap.length; -- if (ixLen == 0) continue; -- int fillp = untypedFirstIndexByTag[tag]; -- assert(cpMap[fillp] == null); -- assert(cpMap[fillp+ixLen-1] == null); -- System.arraycopy(ix.cpMap, 0, cpMap, fillp, ixLen); -- } -- indexUntyped = new Index("untyped", cpMap); -- } -- return indexUntyped; -- } -+ /** Index of all CP entries of all types, in definition order. */ -+ public Index getUntypedIndex() { -+ if (indexUntyped == null) { -+ untypedIndexOf(null); // warm up untypedFirstIndexByTag -+ Entry[] cpMap = new Entry[totalSize]; -+ for (int tag = 0; tag < indexByTag.length; tag++) { -+ Index ix = indexByTag[tag]; -+ if (ix == null) continue; -+ int ixLen = ix.cpMap.length; -+ if (ixLen == 0) continue; -+ int fillp = untypedFirstIndexByTag[tag]; -+ assert(cpMap[fillp] == null); -+ assert(cpMap[fillp+ixLen-1] == null); -+ System.arraycopy(ix.cpMap, 0, cpMap, fillp, ixLen); -+ } -+ indexUntyped = new Index("untyped", cpMap); -+ } -+ return indexUntyped; -+ } - -- public int untypedIndexOf(Entry e) { -- if (untypedFirstIndexByTag == null) { -- untypedFirstIndexByTag = new int[CONSTANT_Limit]; -- int fillp = 0; -- for (int i = 0; i < TAGS_IN_ORDER.length; i++) { -- byte tag = TAGS_IN_ORDER[i]; -- Index ix = indexByTag[tag]; -- if (ix == null) continue; -- int ixLen = ix.cpMap.length; -- untypedFirstIndexByTag[tag] = fillp; -- fillp += ixLen; -- } -- totalSize = fillp; -- } -- if (e == null) return -1; -- int tag = e.tag; -- Index ix = indexByTag[tag]; -- if (ix == null) return -1; -- int idx = ix.findIndexOf(e); -- if (idx >= 0) -- idx += untypedFirstIndexByTag[tag]; -- return idx; -- } -+ public int untypedIndexOf(Entry e) { -+ if (untypedFirstIndexByTag == null) { -+ untypedFirstIndexByTag = new int[CONSTANT_Limit]; -+ int fillp = 0; -+ for (int i = 0; i < TAGS_IN_ORDER.length; i++) { -+ byte tag = TAGS_IN_ORDER[i]; -+ Index ix = indexByTag[tag]; -+ if (ix == null) continue; -+ int ixLen = ix.cpMap.length; -+ untypedFirstIndexByTag[tag] = fillp; -+ fillp += ixLen; -+ } -+ totalSize = fillp; -+ } -+ if (e == null) return -1; -+ int tag = e.tag; -+ Index ix = indexByTag[tag]; -+ if (ix == null) return -1; -+ int idx = ix.findIndexOf(e); -+ if (idx >= 0) -+ idx += untypedFirstIndexByTag[tag]; -+ return idx; -+ } - -- public void initIndexByTag(byte tag, Index ix) { -- assert(indexByTag[tag] == null); // do not init twice -- Entry[] cpMap = ix.cpMap; -- for (int i = 0; i < cpMap.length; i++) { -- // It must be a homogeneous Entry set. -- assert(cpMap[i].tag == tag); -- } -- if (tag == CONSTANT_Utf8) { -- // Special case: First Utf8 must always be empty string. -- assert(cpMap.length == 0 || cpMap[0].stringValue().equals("")); -- } -- indexByTag[tag] = ix; -- // decache indexes derived from this one: -- untypedFirstIndexByTag = null; -- indexUntyped = null; -- if (indexByTagAndClass != null) -- indexByTagAndClass[tag] = null; -- } -+ public void initIndexByTag(byte tag, Index ix) { -+ assert(indexByTag[tag] == null); // do not init twice -+ Entry[] cpMap = ix.cpMap; -+ for (int i = 0; i < cpMap.length; i++) { -+ // It must be a homogeneous Entry set. -+ assert(cpMap[i].tag == tag); -+ } -+ if (tag == CONSTANT_Utf8) { -+ // Special case: First Utf8 must always be empty string. -+ assert(cpMap.length == 0 || cpMap[0].stringValue().equals("")); -+ } -+ indexByTag[tag] = ix; -+ // decache indexes derived from this one: -+ untypedFirstIndexByTag = null; -+ indexUntyped = null; -+ if (indexByTagAndClass != null) -+ indexByTagAndClass[tag] = null; -+ } - -- /** Index of all CP entries of a given tag. */ -- public Index getIndexByTag(byte tag) { -- if (tag == CONSTANT_All) { -- return getUntypedIndex(); -- } -- Index ix = indexByTag[tag]; -- if (ix == null) { -- // Make an empty one by default. -- ix = new Index(tagName(tag), new Entry[0]); -- indexByTag[tag] = ix; -- } -- return ix; -- } -+ /** Index of all CP entries of a given tag. */ -+ public Index getIndexByTag(byte tag) { -+ if (tag == CONSTANT_All) { -+ return getUntypedIndex(); -+ } -+ Index ix = indexByTag[tag]; -+ if (ix == null) { -+ // Make an empty one by default. -+ ix = new Index(tagName(tag), new Entry[0]); -+ indexByTag[tag] = ix; -+ } -+ return ix; -+ } - -- /** Index of all CP entries of a given tag and class. */ -- public Index getMemberIndex(byte tag, ClassEntry classRef) { -- if (indexByTagAndClass == null) -- indexByTagAndClass = new Index[CONSTANT_Limit][]; -- Index allClasses = getIndexByTag(CONSTANT_Class); -- Index[] perClassIndexes = indexByTagAndClass[tag]; -- if (perClassIndexes == null) { -- // Create the partition now. -- // Divide up all entries of the given tag according to their class. -- Index allMembers = getIndexByTag(tag); -- int[] whichClasses = new int[allMembers.size()]; -- for (int i = 0; i < whichClasses.length; i++) { -- MemberEntry e = (MemberEntry) allMembers.get(i); -- int whichClass = allClasses.indexOf(e.classRef); -- whichClasses[i] = whichClass; -- } -- perClassIndexes = partition(allMembers, whichClasses); -- for (int i = 0; i < perClassIndexes.length; i++) -- assert(perClassIndexes[i]==null -- || perClassIndexes[i].assertIsSorted()); -- indexByTagAndClass[tag] = perClassIndexes; -- } -- int whichClass = allClasses.indexOf(classRef); -- return perClassIndexes[whichClass]; -- } -+ /** Index of all CP entries of a given tag and class. */ -+ public Index getMemberIndex(byte tag, ClassEntry classRef) { -+ if (classRef == null) -+ throw new RuntimeException("missing class reference for " + tagName(tag)); -+ if (indexByTagAndClass == null) -+ indexByTagAndClass = new Index[CONSTANT_Limit][]; -+ Index allClasses = getIndexByTag(CONSTANT_Class); -+ Index[] perClassIndexes = indexByTagAndClass[tag]; -+ if (perClassIndexes == null) { -+ // Create the partition now. -+ // Divide up all entries of the given tag according to their class. -+ Index allMembers = getIndexByTag(tag); -+ int[] whichClasses = new int[allMembers.size()]; -+ for (int i = 0; i < whichClasses.length; i++) { -+ MemberEntry e = (MemberEntry) allMembers.get(i); -+ int whichClass = allClasses.indexOf(e.classRef); -+ whichClasses[i] = whichClass; -+ } -+ perClassIndexes = partition(allMembers, whichClasses); -+ for (int i = 0; i < perClassIndexes.length; i++) -+ assert(perClassIndexes[i]==null -+ || perClassIndexes[i].assertIsSorted()); -+ indexByTagAndClass[tag] = perClassIndexes; -+ } -+ int whichClass = allClasses.indexOf(classRef); -+ return perClassIndexes[whichClass]; -+ } - -- // Given the sequence of all methods of the given name and class, -- // produce the ordinal of this particular given overloading. -- public int getOverloadingIndex(MemberEntry methodRef) { -- Index ix = getMemberIndex(methodRef.tag, methodRef.classRef); -- Utf8Entry nameRef = methodRef.descRef.nameRef; -- int ord = 0; -- for (int i = 0; i < ix.cpMap.length; i++) { -- MemberEntry e = (MemberEntry) ix.cpMap[i]; -- if (e.equals(methodRef)) -- return ord; -- if (e.descRef.nameRef.equals(nameRef)) -- // Found a different overloading. Increment the ordinal. -- ord++; -- } -- throw new RuntimeException("should not reach here"); -- } -+ // Given the sequence of all methods of the given name and class, -+ // produce the ordinal of this particular given overloading. -+ public int getOverloadingIndex(MemberEntry methodRef) { -+ Index ix = getMemberIndex(methodRef.tag, methodRef.classRef); -+ Utf8Entry nameRef = methodRef.descRef.nameRef; -+ int ord = 0; -+ for (int i = 0; i < ix.cpMap.length; i++) { -+ MemberEntry e = (MemberEntry) ix.cpMap[i]; -+ if (e.equals(methodRef)) -+ return ord; -+ if (e.descRef.nameRef.equals(nameRef)) -+ // Found a different overloading. Increment the ordinal. -+ ord++; -+ } -+ throw new RuntimeException("should not reach here"); -+ } - -- // Inverse of getOverloadingIndex -- public MemberEntry getOverloadingForIndex(byte tag, ClassEntry classRef, String name, int which) { -- assert(name == name.intern()); -- Index ix = getMemberIndex(tag, classRef); -- int ord = 0; -- for (int i = 0; i < ix.cpMap.length; i++) { -- MemberEntry e = (MemberEntry) ix.cpMap[i]; -- if (e.descRef.nameRef.stringValue() == name) { -- if (ord == which) return e; -- ord++; -- } -- } -- throw new RuntimeException("should not reach here"); -- } -+ // Inverse of getOverloadingIndex -+ public MemberEntry getOverloadingForIndex(byte tag, ClassEntry classRef, String name, int which) { -+ assert(name == name.intern()); -+ Index ix = getMemberIndex(tag, classRef); -+ int ord = 0; -+ for (int i = 0; i < ix.cpMap.length; i++) { -+ MemberEntry e = (MemberEntry) ix.cpMap[i]; -+ if (e.descRef.nameRef.stringValue() == name) { -+ if (ord == which) return e; -+ ord++; -+ } -+ } -+ throw new RuntimeException("should not reach here"); -+ } - -- public boolean haveNumbers() { -- for (byte tag = CONSTANT_Integer; tag <= CONSTANT_Double; tag++) { -- switch (tag) { -- case CONSTANT_Integer: -- case CONSTANT_Float: -- case CONSTANT_Long: -- case CONSTANT_Double: -- break; -- default: -- assert(false); -- } -- if (getIndexByTag(tag).size() > 0) return true; -- } -- return false; -- } -+ public boolean haveNumbers() { -+ for (byte tag = CONSTANT_Integer; tag <= CONSTANT_Double; tag++) { -+ switch (tag) { -+ case CONSTANT_Integer: -+ case CONSTANT_Float: -+ case CONSTANT_Long: -+ case CONSTANT_Double: -+ break; -+ default: -+ assert(false); -+ } -+ if (getIndexByTag(tag).size() > 0) return true; -+ } -+ return false; -+ } - - } - -@@ -1114,84 +1116,84 @@ class ConstantPool implements Constants - */ - public static - void completeReferencesIn(Set cpRefs, boolean flattenSigs) { -- cpRefs.remove(null); -- for (ListIterator work = -- new ArrayList(cpRefs).listIterator(cpRefs.size()); -- work.hasPrevious(); ) { -- Entry e = (Entry) work.previous(); -- work.remove(); // pop stack -- assert(e != null); -- if (flattenSigs && e.tag == CONSTANT_Signature) { -- SignatureEntry se = (SignatureEntry) e; -- Utf8Entry ue = se.asUtf8Entry(); -- // Totally replace e by se. -- cpRefs.remove(se); -- cpRefs.add(ue); -- e = ue; // do not descend into the sig -- } -- // Recursively add the refs of e to cpRefs: -- for (int i = 0; ; i++) { -- Entry re = e.getRef(i); -- if (re == null) -- break; // no more refs in e -- if (cpRefs.add(re)) // output the ref -- work.add(re); // push stack, if a new ref -- } -- } -+ cpRefs.remove(null); -+ for (ListIterator work = -+ new ArrayList(cpRefs).listIterator(cpRefs.size()); -+ work.hasPrevious(); ) { -+ Entry e = (Entry) work.previous(); -+ work.remove(); // pop stack -+ assert(e != null); -+ if (flattenSigs && e.tag == CONSTANT_Signature) { -+ SignatureEntry se = (SignatureEntry) e; -+ Utf8Entry ue = se.asUtf8Entry(); -+ // Totally replace e by se. -+ cpRefs.remove(se); -+ cpRefs.add(ue); -+ e = ue; // do not descend into the sig -+ } -+ // Recursively add the refs of e to cpRefs: -+ for (int i = 0; ; i++) { -+ Entry re = e.getRef(i); -+ if (re == null) -+ break; // no more refs in e -+ if (cpRefs.add(re)) // output the ref -+ work.add(re); // push stack, if a new ref -+ } -+ } - } - - static double percent(int num, int den) { -- return (int)((10000.0*num)/den + 0.5) / 100.0; -+ return (int)((10000.0*num)/den + 0.5) / 100.0; - } - - public static String tagName(int tag) { -- switch (tag) { -- case CONSTANT_Utf8: return "Utf8"; -- case CONSTANT_Integer: return "Integer"; -- case CONSTANT_Float: return "Float"; -- case CONSTANT_Long: return "Long"; -- case CONSTANT_Double: return "Double"; -- case CONSTANT_Class: return "Class"; -- case CONSTANT_String: return "String"; -- case CONSTANT_Fieldref: return "Fieldref"; -- case CONSTANT_Methodref: return "Methodref"; -- case CONSTANT_InterfaceMethodref: return "InterfaceMethodref"; -- case CONSTANT_NameandType: return "NameandType"; -+ switch (tag) { -+ case CONSTANT_Utf8: return "Utf8"; -+ case CONSTANT_Integer: return "Integer"; -+ case CONSTANT_Float: return "Float"; -+ case CONSTANT_Long: return "Long"; -+ case CONSTANT_Double: return "Double"; -+ case CONSTANT_Class: return "Class"; -+ case CONSTANT_String: return "String"; -+ case CONSTANT_Fieldref: return "Fieldref"; -+ case CONSTANT_Methodref: return "Methodref"; -+ case CONSTANT_InterfaceMethodref: return "InterfaceMethodref"; -+ case CONSTANT_NameandType: return "NameandType"; - -- // pseudo-tags: -- case CONSTANT_All: return "*All"; -- case CONSTANT_None: return "*None"; -- case CONSTANT_Signature: return "*Signature"; -- } -- return "tag#"+tag; -+ // pseudo-tags: -+ case CONSTANT_All: return "*All"; -+ case CONSTANT_None: return "*None"; -+ case CONSTANT_Signature: return "*Signature"; -+ } -+ return "tag#"+tag; - } - - // archive constant pool definition order - static final byte TAGS_IN_ORDER[] = { -- CONSTANT_Utf8, -- CONSTANT_Integer, // cp_Int -- CONSTANT_Float, -- CONSTANT_Long, -- CONSTANT_Double, -- CONSTANT_String, -- CONSTANT_Class, -- CONSTANT_Signature, -- CONSTANT_NameandType, // cp_Descr -- CONSTANT_Fieldref, // cp_Field -- CONSTANT_Methodref, // cp_Method -- CONSTANT_InterfaceMethodref // cp_Imethod -+ CONSTANT_Utf8, -+ CONSTANT_Integer, // cp_Int -+ CONSTANT_Float, -+ CONSTANT_Long, -+ CONSTANT_Double, -+ CONSTANT_String, -+ CONSTANT_Class, -+ CONSTANT_Signature, -+ CONSTANT_NameandType, // cp_Descr -+ CONSTANT_Fieldref, // cp_Field -+ CONSTANT_Methodref, // cp_Method -+ CONSTANT_InterfaceMethodref // cp_Imethod - }; - static final byte TAG_ORDER[]; - static { -- TAG_ORDER = new byte[CONSTANT_Limit]; -- for (int i = 0; i < TAGS_IN_ORDER.length; i++) { -- TAG_ORDER[TAGS_IN_ORDER[i]] = (byte)(i+1); -- } -- /* -- System.out.println("TAG_ORDER[] = {"); -- for (int i = 0; i < TAG_ORDER.length; i++) -- System.out.println(" "+TAG_ORDER[i]+","); -- System.out.println("};"); -- */ -+ TAG_ORDER = new byte[CONSTANT_Limit]; -+ for (int i = 0; i < TAGS_IN_ORDER.length; i++) { -+ TAG_ORDER[TAGS_IN_ORDER[i]] = (byte)(i+1); -+ } -+ /* -+ System.out.println("TAG_ORDER[] = {"); -+ for (int i = 0; i < TAG_ORDER.length; i++) -+ System.out.println(" "+TAG_ORDER[i]+","); -+ System.out.println("};"); -+ */ - } - } -diff --git a/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java b/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java ---- jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java -+++ jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -22,7 +22,6 @@ - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -- - - package com.sun.java.util.jar.pack; - -@@ -81,239 +80,246 @@ class NativeUnpack { - private PropMap _props; - - static { -- // If loading from stand alone build uncomment this. -- // System.loadLibrary("unpack"); -- java.security.AccessController.doPrivileged( -- new sun.security.action.LoadLibraryAction("unpack")); -- initIDs(); -+ // If loading from stand alone build uncomment this. -+ // System.loadLibrary("unpack"); -+ java.security.AccessController.doPrivileged( -+ new sun.security.action.LoadLibraryAction("unpack")); -+ initIDs(); - } -- -+ - NativeUnpack(UnpackerImpl p200) { -- super(); -- _p200 = p200; -- _props = p200._props; -- p200._nunp = this; -+ super(); -+ _p200 = p200; -+ _props = p200._props; -+ p200._nunp = this; - } - - // for JNI callbacks - static private Object currentInstance() { -- UnpackerImpl p200 = (UnpackerImpl) Utils.currentInstance.get(); -- return (p200 == null)? null: p200._nunp; -+ UnpackerImpl p200 = (UnpackerImpl) Utils.currentInstance.get(); -+ return (p200 == null)? null: p200._nunp; -+ } -+ -+ private synchronized long getUnpackerPtr() { -+ return unpackerPtr; - } - - // Callback from the unpacker engine to get more data. - private long readInputFn(ByteBuffer pbuf, long minlen) throws IOException { -- if (in == null) return 0; // nothing is readable -- long maxlen = pbuf.capacity() - pbuf.position(); -- assert(minlen <= maxlen); // don't talk nonsense -- long numread = 0; -- int steps = 0; -- while (numread < minlen) { -- steps++; -- // read available input, up to buf.length or maxlen -- int readlen = _buf.length; -- if (readlen > (maxlen - numread)) -- readlen = (int)(maxlen - numread); -- int nr = in.read(_buf, 0, readlen); -- if (nr <= 0) break; -- numread += nr; -- assert(numread <= maxlen); -- // %%% get rid of this extra copy by using nio? -- pbuf.put(_buf, 0, nr); -- } -- if (_verbose > 1) -- Utils.log.fine("readInputFn("+minlen+","+maxlen+") => "+numread+" steps="+steps); -- if (maxlen > 100) { -- _estByteLimit = _byteCount + maxlen; -- } else { -- _estByteLimit = (_byteCount + numread) * 20; -- } -- _byteCount += numread; -- updateProgress(); -- return numread; -+ if (in == null) return 0; // nothing is readable -+ long maxlen = pbuf.capacity() - pbuf.position(); -+ assert(minlen <= maxlen); // don't talk nonsense -+ long numread = 0; -+ int steps = 0; -+ while (numread < minlen) { -+ steps++; -+ // read available input, up to buf.length or maxlen -+ int readlen = _buf.length; -+ if (readlen > (maxlen - numread)) -+ readlen = (int)(maxlen - numread); -+ int nr = in.read(_buf, 0, readlen); -+ if (nr <= 0) break; -+ numread += nr; -+ assert(numread <= maxlen); -+ // %%% get rid of this extra copy by using nio? -+ pbuf.put(_buf, 0, nr); -+ } -+ if (_verbose > 1) -+ Utils.log.fine("readInputFn("+minlen+","+maxlen+") => "+numread+" steps="+steps); -+ if (maxlen > 100) { -+ _estByteLimit = _byteCount + maxlen; -+ } else { -+ _estByteLimit = (_byteCount + numread) * 20; -+ } -+ _byteCount += numread; -+ updateProgress(); -+ return numread; - } - - private void updateProgress() { -- // Progress is a combination of segment reading and file writing. -- final double READ_WT = 0.33; -- final double WRITE_WT = 0.67; -- double readProgress = _segCount; -- if (_estByteLimit > 0 && _byteCount > 0) -- readProgress += (double)_byteCount / _estByteLimit; -- double writeProgress = _fileCount; -- double scaledProgress -- = READ_WT * readProgress / Math.max(_estSegLimit,1) -- + WRITE_WT * writeProgress / Math.max(_estFileLimit,1); -- int percent = (int) Math.round(100*scaledProgress); -- if (percent > 100) percent = 100; -- if (percent > _prevPercent) { -- _prevPercent = percent; -- _props.setInteger(Pack200.Unpacker.PROGRESS, percent); -- if (_verbose > 0) -- Utils.log.info("progress = "+percent); -- } -+ // Progress is a combination of segment reading and file writing. -+ final double READ_WT = 0.33; -+ final double WRITE_WT = 0.67; -+ double readProgress = _segCount; -+ if (_estByteLimit > 0 && _byteCount > 0) -+ readProgress += (double)_byteCount / _estByteLimit; -+ double writeProgress = _fileCount; -+ double scaledProgress -+ = READ_WT * readProgress / Math.max(_estSegLimit,1) -+ + WRITE_WT * writeProgress / Math.max(_estFileLimit,1); -+ int percent = (int) Math.round(100*scaledProgress); -+ if (percent > 100) percent = 100; -+ if (percent > _prevPercent) { -+ _prevPercent = percent; -+ _props.setInteger(Pack200.Unpacker.PROGRESS, percent); -+ if (_verbose > 0) -+ Utils.log.info("progress = "+percent); -+ } - } - - private void copyInOption(String opt) { -- String val = _props.getProperty(opt); -- if (_verbose > 0) -- Utils.log.info("set "+opt+"="+val); -- if (val != null) { -- boolean set = setOption(opt, val); -- if (!set) -- Utils.log.warning("Invalid option "+opt+"="+val); -- } -+ String val = _props.getProperty(opt); -+ if (_verbose > 0) -+ Utils.log.info("set "+opt+"="+val); -+ if (val != null) { -+ boolean set = setOption(opt, val); -+ if (!set) -+ Utils.log.warning("Invalid option "+opt+"="+val); -+ } - } - - void run(InputStream inRaw, JarOutputStream jstream, -- ByteBuffer presetInput) throws IOException { -- BufferedInputStream in = new BufferedInputStream(inRaw); -- this.in = in; // for readInputFn to see -- _verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -- // Fix for BugId: 4902477, -unpack.modification.time = 1059010598000 -+ ByteBuffer presetInput) throws IOException { -+ BufferedInputStream in = new BufferedInputStream(inRaw); -+ this.in = in; // for readInputFn to see -+ _verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -+ // Fix for BugId: 4902477, -unpack.modification.time = 1059010598000 - // TODO eliminate and fix in unpack.cpp -+ -+ final int modtime = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, "0")) ? -+ Constants.NO_MODTIME : _props.getTime(Utils.UNPACK_MODIFICATION_TIME); - -- final int modtime = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, "0")) ? -- Constants.NO_MODTIME : _props.getTime(Utils.UNPACK_MODIFICATION_TIME); -+ copyInOption(Utils.DEBUG_VERBOSE); -+ copyInOption(Pack200.Unpacker.DEFLATE_HINT); -+ if (modtime == Constants.NO_MODTIME) // Dont pass KEEP && NOW -+ copyInOption(Utils.UNPACK_MODIFICATION_TIME); -+ updateProgress(); // reset progress bar -+ for (;;) { -+ // Read the packed bits. -+ long counts = start(presetInput, 0); -+ _byteCount = _estByteLimit = 0; // reset partial scan counts -+ ++_segCount; // just finished scanning a whole segment... -+ int nextSeg = (int)( counts >>> 32 ); -+ int nextFile = (int)( counts >>> 0 ); - -- copyInOption(Utils.DEBUG_VERBOSE); -- copyInOption(Pack200.Unpacker.DEFLATE_HINT); -- if (modtime == Constants.NO_MODTIME) // Dont pass KEEP && NOW -- copyInOption(Utils.UNPACK_MODIFICATION_TIME); -- updateProgress(); // reset progress bar -- for (;;) { -- // Read the packed bits. -- long counts = start(presetInput, 0); -- _byteCount = _estByteLimit = 0; // reset partial scan counts -- ++_segCount; // just finished scanning a whole segment... -- int nextSeg = (int)( counts >>> 32 ); -- int nextFile = (int)( counts >>> 0 ); -+ // Estimate eventual total number of segments and files. -+ _estSegLimit = _segCount + nextSeg; -+ double filesAfterThisSeg = _fileCount + nextFile; -+ _estFileLimit = (int)( (filesAfterThisSeg * -+ _estSegLimit) / _segCount ); - -- // Estimate eventual total number of segments and files. -- _estSegLimit = _segCount + nextSeg; -- double filesAfterThisSeg = _fileCount + nextFile; -- _estFileLimit = (int)( (filesAfterThisSeg * -- _estSegLimit) / _segCount ); -+ // Write the files. -+ int[] intParts = { 0,0, 0, 0 }; -+ // intParts = {size.hi/lo, mod, defl} -+ Object[] parts = { intParts, null, null, null }; -+ // parts = { {intParts}, name, data0/1 } -+ while (getNextFile(parts)) { -+ //BandStructure.printArrayTo(System.out, intParts, 0, parts.length); -+ String name = (String) parts[1]; -+ long size = ( (long)intParts[0] << 32) -+ + (((long)intParts[1] << 32) >>> 32); - -- // Write the files. -- int[] intParts = { 0,0, 0, 0 }; -- // intParts = {size.hi/lo, mod, defl} -- Object[] parts = { intParts, null, null, null }; -- // parts = { {intParts}, name, data0/1 } -- while (getNextFile(parts)) { -- //BandStructure.printArrayTo(System.out, intParts, 0, parts.length); -- String name = (String) parts[1]; -- long size = ( (long)intParts[0] << 32) -- + (((long)intParts[1] << 32) >>> 32); -- -- long mtime = (modtime != Constants.NO_MODTIME ) ? -- modtime : intParts[2] ; -- boolean deflateHint = (intParts[3] != 0); -- ByteBuffer data0 = (ByteBuffer) parts[2]; -- ByteBuffer data1 = (ByteBuffer) parts[3]; -- writeEntry(jstream, name, mtime, size, deflateHint, -- data0, data1); -- ++_fileCount; -- updateProgress(); -- } -- long consumed = finish(); -- if (_verbose > 0) -- Utils.log.info("bytes consumed = "+consumed); -- presetInput = getUnusedInput(); -- if (presetInput == null && -- !Utils.isPackMagic(Utils.readMagic(in))) { -- break; -- } -- if (_verbose > 0 ) { -- if (presetInput != null) -- Utils.log.info("unused input = "+presetInput); -- } -- } -+ long mtime = (modtime != Constants.NO_MODTIME ) ? -+ modtime : intParts[2] ; -+ boolean deflateHint = (intParts[3] != 0); -+ ByteBuffer data0 = (ByteBuffer) parts[2]; -+ ByteBuffer data1 = (ByteBuffer) parts[3]; -+ writeEntry(jstream, name, mtime, size, deflateHint, -+ data0, data1); -+ ++_fileCount; -+ updateProgress(); -+ } -+ long consumed = finish(); -+ if (_verbose > 0) -+ Utils.log.info("bytes consumed = "+consumed); -+ presetInput = getUnusedInput(); -+ if (presetInput == null && -+ !Utils.isPackMagic(Utils.readMagic(in))) { -+ break; -+ } -+ if (_verbose > 0 ) { -+ if (presetInput != null) -+ Utils.log.info("unused input = "+presetInput); -+ } -+ } - } - - void run(InputStream in, JarOutputStream jstream) throws IOException { -- run(in, jstream, null); -+ run(in, jstream, null); - } - - void run(File inFile, JarOutputStream jstream) throws IOException { -- // %%% maybe memory-map the file, and pass it straight into unpacker -- ByteBuffer mappedFile = null; -- FileInputStream fis = new FileInputStream(inFile); -- run(fis, jstream, mappedFile); -- fis.close(); -- // Note: caller is responsible to finish with jstream. -+ // %%% maybe memory-map the file, and pass it straight into unpacker -+ ByteBuffer mappedFile = null; -+ FileInputStream fis = new FileInputStream(inFile); -+ run(fis, jstream, mappedFile); -+ fis.close(); -+ // Note: caller is responsible to finish with jstream. - } -+ -+ private void writeEntry(JarOutputStream j, String name, -+ long mtime, long lsize, boolean deflateHint, -+ ByteBuffer data0, ByteBuffer data1) throws IOException { -+ int size = (int)lsize; -+ if (size != lsize) -+ throw new IOException("file too large: "+lsize); - -- private void writeEntry(JarOutputStream j, String name, -- long mtime, long lsize, boolean deflateHint, -- ByteBuffer data0, ByteBuffer data1) throws IOException { -- int size = (int)lsize; -- if (size != lsize) -- throw new IOException("file too large: "+lsize); -+ CRC32 crc32 = _crc32; - -- CRC32 crc32 = _crc32; -+ if (_verbose > 1) -+ Utils.log.fine("Writing entry: "+name+" size="+size -+ +(deflateHint?" deflated":"")); - -- if (_verbose > 1) -- Utils.log.fine("Writing entry: "+name+" size="+size -- +(deflateHint?" deflated":"")); -+ if (_buf.length < size) { -+ int newSize = size; -+ while (newSize < _buf.length) { -+ newSize <<= 1; -+ if (newSize <= 0) { -+ newSize = size; -+ break; -+ } -+ } -+ _buf = new byte[newSize]; -+ } -+ assert(_buf.length >= size); - -- if (_buf.length < size) { -- int newSize = size; -- while (newSize < _buf.length) { -- newSize <<= 1; -- if (newSize <= 0) { -- newSize = size; -- break; -- } -- } -- _buf = new byte[newSize]; -- } -- assert(_buf.length >= size); -+ int fillp = 0; -+ if (data0 != null) { -+ int size0 = data0.capacity(); -+ data0.get(_buf, fillp, size0); -+ fillp += size0; -+ } -+ if (data1 != null) { -+ int size1 = data1.capacity(); -+ data1.get(_buf, fillp, size1); -+ fillp += size1; -+ } -+ while (fillp < size) { -+ // Fill in rest of data from the stream itself. -+ int nr = in.read(_buf, fillp, size - fillp); -+ if (nr <= 0) throw new IOException("EOF at end of archive"); -+ fillp += nr; -+ } - -- int fillp = 0; -- if (data0 != null) { -- int size0 = data0.capacity(); -- data0.get(_buf, fillp, size0); -- fillp += size0; -- } -- if (data1 != null) { -- int size1 = data1.capacity(); -- data1.get(_buf, fillp, size1); -- fillp += size1; -- } -- while (fillp < size) { -- // Fill in rest of data from the stream itself. -- int nr = in.read(_buf, fillp, size - fillp); -- if (nr <= 0) throw new IOException("EOF at end of archive"); -- fillp += nr; -- } -+ ZipEntry z = new ZipEntry(name); -+ z.setTime( (long)mtime * 1000); -+ -+ if (size == 0) { -+ z.setMethod(ZipOutputStream.STORED); -+ z.setSize(0); -+ z.setCrc(0); -+ z.setCompressedSize(0); -+ } else if (!deflateHint) { -+ z.setMethod(ZipOutputStream.STORED); -+ z.setSize(size); -+ z.setCompressedSize(size); -+ crc32.reset(); -+ crc32.update(_buf, 0, size); -+ z.setCrc(crc32.getValue()); -+ } else { -+ z.setMethod(Deflater.DEFLATED); -+ z.setSize(size); -+ } - -- ZipEntry z = new ZipEntry(name); -- z.setTime( (long)mtime * 1000); -+ j.putNextEntry(z); - -- if (size == 0) { -- z.setMethod(ZipOutputStream.STORED); -- z.setSize(0); -- z.setCrc(0); -- z.setCompressedSize(0); -- } else if (!deflateHint) { -- z.setMethod(ZipOutputStream.STORED); -- z.setSize(size); -- z.setCompressedSize(size); -- crc32.reset(); -- crc32.update(_buf, 0, size); -- z.setCrc(crc32.getValue()); -- } else { -- z.setMethod(Deflater.DEFLATED); -- z.setSize(size); -- } -+ if (size > 0) -+ j.write(_buf, 0, size); - -- j.putNextEntry(z); -- -- if (size > 0) -- j.write(_buf, 0, size); -- -- j.closeEntry(); -- if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z)); -+ j.closeEntry(); -+ if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z)); - } - } -+ -+ -+ -diff --git a/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java b/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java ---- jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java -+++ jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -22,7 +22,6 @@ - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -- - package com.sun.java.util.jar.pack; - - import java.util.*; -@@ -48,9 +47,9 @@ public class PackerImpl implements Pack2 - * the packer engines. - */ - public PackerImpl() { -- _props = new PropMap(); -- //_props.getProperty() consults defaultProps invisibly. -- //_props.putAll(defaultProps); -+ _props = new PropMap(); -+ //_props.getProperty() consults defaultProps invisibly. -+ //_props.putAll(defaultProps); - } - - -@@ -62,7 +61,7 @@ public class PackerImpl implements Pack2 - * @return A sorted association of option key strings to option values. - */ - public SortedMap properties() { -- return _props; -+ return _props; - } - - -@@ -76,24 +75,24 @@ public class PackerImpl implements Pack2 - * @param out an OutputStream - * @exception IOException if an error is encountered. - */ -- public void pack(JarFile in, OutputStream out) throws IOException { -- assert(Utils.currentInstance.get() == null); -- TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : -- TimeZone.getDefault(); -- try { -- Utils.currentInstance.set(this); -- if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); -+ public synchronized void pack(JarFile in, OutputStream out) throws IOException { -+ assert(Utils.currentInstance.get() == null); -+ TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : -+ TimeZone.getDefault(); -+ try { -+ Utils.currentInstance.set(this); -+ if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - -- if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) { -- Utils.copyJarFile(in, out); -- } else { -- (new DoPack()).run(in, out); -- in.close(); -- } -- } finally { -- Utils.currentInstance.set(null); -- if (tz != null) TimeZone.setDefault(tz); -- } -+ if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) { -+ Utils.copyJarFile(in, out); -+ } else { -+ (new DoPack()).run(in, out); -+ in.close(); -+ } -+ } finally { -+ Utils.currentInstance.set(null); -+ if (tz != null) TimeZone.setDefault(tz); -+ } - } - - /** -@@ -110,39 +109,39 @@ public class PackerImpl implements Pack2 - * @param out an OutputStream - * @exception IOException if an error is encountered. - */ -- public void pack(JarInputStream in, OutputStream out) throws IOException { -- assert(Utils.currentInstance.get() == null); -- TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : -- TimeZone.getDefault(); -- try { -- Utils.currentInstance.set(this); -- if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); -- if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) { -- Utils.copyJarFile(in, out); -- } else { -- (new DoPack()).run(in, out); -- in.close(); -- } -- } finally { -- Utils.currentInstance.set(null); -- if (tz != null) TimeZone.setDefault(tz); -+ public synchronized void pack(JarInputStream in, OutputStream out) throws IOException { -+ assert(Utils.currentInstance.get() == null); -+ TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : -+ TimeZone.getDefault(); -+ try { -+ Utils.currentInstance.set(this); -+ if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); -+ if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) { -+ Utils.copyJarFile(in, out); -+ } else { -+ (new DoPack()).run(in, out); -+ in.close(); -+ } -+ } finally { -+ Utils.currentInstance.set(null); -+ if (tz != null) TimeZone.setDefault(tz); - -- } -+ } - } - /** - * Register a listener for changes to options. -- * @param listener An object to be invoked when a property is changed. -+ * @param listener An object to be invoked when a property is changed. - */ - public void addPropertyChangeListener(PropertyChangeListener listener) { -- _props.addListener(listener); -+ _props.addListener(listener); - } - - /** - * Remove a listener for the PropertyChange event. -- * @param listener The PropertyChange listener to be removed. -+ * @param listener The PropertyChange listener to be removed. - */ - public void removePropertyChangeListener(PropertyChangeListener listener) { -- _props.removeListener(listener); -+ _props.removeListener(listener); - } - - -@@ -151,471 +150,478 @@ public class PackerImpl implements Pack2 - - // The packer worker. - private class DoPack { -- final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -+ final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); - -- { -- _props.setInteger(Pack200.Packer.PROGRESS, 0); -- if (verbose > 0) Utils.log.info(_props.toString()); -- } -+ { -+ _props.setInteger(Pack200.Packer.PROGRESS, 0); -+ if (verbose > 0) Utils.log.info(_props.toString()); -+ } - -- // Here's where the bits are collected before getting packed: -- final Package pkg = new Package(); -+ // Here's where the bits are collected before getting packed: -+ final Package pkg = new Package(); - -- final String unknownAttrCommand; -- { -- String uaMode = _props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS); -- if (!(Pack200.Packer.STRIP.equals(uaMode) || -- Pack200.Packer.PASS.equals(uaMode) || -- Pack200.Packer.ERROR.equals(uaMode))) { -- throw new RuntimeException("Bad option: " + Pack200.Packer.UNKNOWN_ATTRIBUTE + " = " + uaMode); -- } -- unknownAttrCommand = uaMode.intern(); -- } -+ final String unknownAttrCommand; -+ { -+ String uaMode = _props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS); -+ if (!(Pack200.Packer.STRIP.equals(uaMode) || -+ Pack200.Packer.PASS.equals(uaMode) || -+ Pack200.Packer.ERROR.equals(uaMode))) { -+ throw new RuntimeException("Bad option: " + Pack200.Packer.UNKNOWN_ATTRIBUTE + " = " + uaMode); -+ } -+ unknownAttrCommand = uaMode.intern(); -+ } - -- final HashMap attrDefs; -- final HashMap attrCommands; -- { -- HashMap attrDefs = new HashMap(); -- HashMap attrCommands = new HashMap(); -- String[] keys = { -- Pack200.Packer.CLASS_ATTRIBUTE_PFX, -- Pack200.Packer.FIELD_ATTRIBUTE_PFX, -- Pack200.Packer.METHOD_ATTRIBUTE_PFX, -- Pack200.Packer.CODE_ATTRIBUTE_PFX -- }; -- int[] ctypes = { -- Constants.ATTR_CONTEXT_CLASS, -- Constants.ATTR_CONTEXT_FIELD, -- Constants.ATTR_CONTEXT_METHOD, -- Constants.ATTR_CONTEXT_CODE -- }; -- for (int i = 0; i < ctypes.length; i++) { -- String pfx = keys[i]; -- Map map = _props.prefixMap(pfx); -- for (Iterator j = map.keySet().iterator(); j.hasNext(); ) { -- String key = (String) j.next(); -- assert(key.startsWith(pfx)); -- String name = key.substring(pfx.length()); -- String layout = _props.getProperty(key); -- Object lkey = Attribute.keyForLookup(ctypes[i], name); -- if (Pack200.Packer.STRIP.equals(layout) || -- Pack200.Packer.PASS.equals(layout) || -- Pack200.Packer.ERROR.equals(layout)) { -- attrCommands.put(lkey, layout.intern()); -- } else { -- Attribute.define(attrDefs, ctypes[i], name, layout); -- if (verbose > 1) { -- Utils.log.fine("Added layout for "+Constants.ATTR_CONTEXT_NAME[i]+" attribute "+name+" = "+layout); -- } -- assert(attrDefs.containsKey(lkey)); -- } -- } -- } -- if (attrDefs.size() > 0) -- this.attrDefs = attrDefs; -- else -- this.attrDefs = null; -- if (attrCommands.size() > 0) -- this.attrCommands = attrCommands; -- else -- this.attrCommands = null; -- } -+ final HashMap attrDefs; -+ final HashMap attrCommands; -+ { -+ HashMap attrDefs = new HashMap(); -+ HashMap attrCommands = new HashMap(); -+ String[] keys = { -+ Pack200.Packer.CLASS_ATTRIBUTE_PFX, -+ Pack200.Packer.FIELD_ATTRIBUTE_PFX, -+ Pack200.Packer.METHOD_ATTRIBUTE_PFX, -+ Pack200.Packer.CODE_ATTRIBUTE_PFX -+ }; -+ int[] ctypes = { -+ Constants.ATTR_CONTEXT_CLASS, -+ Constants.ATTR_CONTEXT_FIELD, -+ Constants.ATTR_CONTEXT_METHOD, -+ Constants.ATTR_CONTEXT_CODE -+ }; -+ for (int i = 0; i < ctypes.length; i++) { -+ String pfx = keys[i]; -+ Map map = _props.prefixMap(pfx); -+ for (Iterator j = map.keySet().iterator(); j.hasNext(); ) { -+ String key = (String) j.next(); -+ assert(key.startsWith(pfx)); -+ String name = key.substring(pfx.length()); -+ String layout = _props.getProperty(key); -+ Object lkey = Attribute.keyForLookup(ctypes[i], name); -+ if (Pack200.Packer.STRIP.equals(layout) || -+ Pack200.Packer.PASS.equals(layout) || -+ Pack200.Packer.ERROR.equals(layout)) { -+ attrCommands.put(lkey, layout.intern()); -+ } else { -+ Attribute.define(attrDefs, ctypes[i], name, layout); -+ if (verbose > 1) { -+ Utils.log.fine("Added layout for "+Constants.ATTR_CONTEXT_NAME[i]+" attribute "+name+" = "+layout); -+ } -+ assert(attrDefs.containsKey(lkey)); -+ } -+ } -+ } -+ if (attrDefs.size() > 0) -+ this.attrDefs = attrDefs; -+ else -+ this.attrDefs = null; -+ if (attrCommands.size() > 0) -+ this.attrCommands = attrCommands; -+ else -+ this.attrCommands = null; -+ } - -- final boolean keepFileOrder -- = _props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER); -- final boolean keepClassOrder -- = _props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER); -+ final boolean keepFileOrder -+ = _props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER); -+ final boolean keepClassOrder -+ = _props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER); - -- final boolean keepModtime -- = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME)); -- final boolean latestModtime -- = Pack200.Packer.LATEST.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME)); -- final boolean keepDeflateHint -- = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.DEFLATE_HINT)); -- { -- if (!keepModtime && !latestModtime) { -- int modtime = _props.getTime(Pack200.Packer.MODIFICATION_TIME); -- if (modtime != Constants.NO_MODTIME) { -- pkg.default_modtime = modtime; -- } -- } -- if (!keepDeflateHint) { -- boolean deflate_hint = _props.getBoolean(Pack200.Packer.DEFLATE_HINT); -- if (deflate_hint) { -- pkg.default_options |= Constants.AO_DEFLATE_HINT; -- } -- } -- } -+ final boolean keepModtime -+ = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME)); -+ final boolean latestModtime -+ = Pack200.Packer.LATEST.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME)); -+ final boolean keepDeflateHint -+ = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.DEFLATE_HINT)); -+ { -+ if (!keepModtime && !latestModtime) { -+ int modtime = _props.getTime(Pack200.Packer.MODIFICATION_TIME); -+ if (modtime != Constants.NO_MODTIME) { -+ pkg.default_modtime = modtime; -+ } -+ } -+ if (!keepDeflateHint) { -+ boolean deflate_hint = _props.getBoolean(Pack200.Packer.DEFLATE_HINT); -+ if (deflate_hint) { -+ pkg.default_options |= Constants.AO_DEFLATE_HINT; -+ } -+ } -+ } - -- long totalOutputSize = 0; -- int segmentCount = 0; -- long segmentTotalSize = 0; -- long segmentSize = 0; // running counter -- final long segmentLimit; -- { -- long limit; -- if (_props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals("")) -- limit = -1; -- else -- limit = _props.getLong(Pack200.Packer.SEGMENT_LIMIT); -- limit = Math.min(Integer.MAX_VALUE, limit); -- limit = Math.max(-1, limit); -- if (limit == -1) -- limit = Long.MAX_VALUE; -- segmentLimit = limit; -- } -+ long totalOutputSize = 0; -+ int segmentCount = 0; -+ long segmentTotalSize = 0; -+ long segmentSize = 0; // running counter -+ final long segmentLimit; -+ { -+ long limit; -+ if (_props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals("")) -+ limit = -1; -+ else -+ limit = _props.getLong(Pack200.Packer.SEGMENT_LIMIT); -+ limit = Math.min(Integer.MAX_VALUE, limit); -+ limit = Math.max(-1, limit); -+ if (limit == -1) -+ limit = Long.MAX_VALUE; -+ segmentLimit = limit; -+ } - -- final List passFiles; // parsed pack.pass.file options -- { -- // Which class files will be passed through? -- passFiles = _props.getProperties(Pack200.Packer.PASS_FILE_PFX); -- for (ListIterator i = passFiles.listIterator(); i.hasNext(); ) { -- String file = (String) i.next(); -- if (file == null) { i.remove(); continue; } -- file = Utils.getJarEntryName(file); // normalize '\\' to '/' -- if (file.endsWith("/")) -- file = file.substring(0, file.length()-1); -- i.set(file); -- } -- if (verbose > 0) Utils.log.info("passFiles = " + passFiles); -- } -+ final List passFiles; // parsed pack.pass.file options -+ { -+ // Which class files will be passed through? -+ passFiles = _props.getProperties(Pack200.Packer.PASS_FILE_PFX); -+ for (ListIterator i = passFiles.listIterator(); i.hasNext(); ) { -+ String file = (String) i.next(); -+ if (file == null) { i.remove(); continue; } -+ file = Utils.getJarEntryName(file); // normalize '\\' to '/' -+ if (file.endsWith("/")) -+ file = file.substring(0, file.length()-1); -+ i.set(file); -+ } -+ if (verbose > 0) Utils.log.info("passFiles = " + passFiles); -+ } - -- { -- // Fill in permitted range of major/minor version numbers. -- int ver; -- if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0) -- pkg.min_class_majver = (short) ver; -- if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0) -- pkg.min_class_minver = (short) ver; -- if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0) -- pkg.max_class_majver = (short) ver; -- if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0) -- pkg.max_class_minver = (short) ver; -- if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0) -- pkg.package_minver = (short) ver; -- if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0) -- pkg.package_majver = (short) ver; -- } -+ { -+ // Fill in permitted range of major/minor version numbers. -+ int ver; -+ if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0) -+ pkg.min_class_majver = (short) ver; -+ if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0) -+ pkg.min_class_minver = (short) ver; -+ if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0) -+ pkg.max_class_majver = (short) ver; -+ if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0) -+ pkg.max_class_minver = (short) ver; -+ if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0) -+ pkg.package_minver = (short) ver; -+ if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0) -+ pkg.package_majver = (short) ver; -+ } - -- { -- // Hook for testing: Forces use of special archive modes. -- int opt = _props.getInteger(Utils.COM_PREFIX+"archive.options"); -- if (opt != 0) -- pkg.default_options |= opt; -- } -+ { -+ // Hook for testing: Forces use of special archive modes. -+ int opt = _props.getInteger(Utils.COM_PREFIX+"archive.options"); -+ if (opt != 0) -+ pkg.default_options |= opt; -+ } - -- // (Done collecting options from _props.) -+ // (Done collecting options from _props.) - -- boolean isClassFile(String name) { -- if (!name.endsWith(".class")) return false; -- for (String prefix = name; ; ) { -- if (passFiles.contains(prefix)) return false; -- int chop = prefix.lastIndexOf('/'); -- if (chop < 0) break; -- prefix = prefix.substring(0, chop); -- } -- return true; -- } -+ boolean isClassFile(String name) { -+ if (!name.endsWith(".class")) return false; -+ for (String prefix = name; ; ) { -+ if (passFiles.contains(prefix)) return false; -+ int chop = prefix.lastIndexOf('/'); -+ if (chop < 0) break; -+ prefix = prefix.substring(0, chop); -+ } -+ return true; -+ } - -- boolean isMetaInfFile(String name) { -- return name.startsWith("/" + Utils.METAINF) || -- name.startsWith(Utils.METAINF); -- } -+ boolean isMetaInfFile(String name) { -+ return name.startsWith("/" + Utils.METAINF) || -+ name.startsWith(Utils.METAINF); -+ } - -- // Get a new package, based on the old one. -- private void makeNextPackage() { -- pkg.reset(); -- } -+ // Get a new package, based on the old one. -+ private void makeNextPackage() { -+ pkg.reset(); -+ } - -- class InFile { -- final String name; -- final JarFile jf; -- final JarEntry je; -- final File f; -- int modtime = Constants.NO_MODTIME; -- int options; -- InFile(String name) { -- this.name = Utils.getJarEntryName(name); -- this.f = new File(name); -- this.jf = null; -- this.je = null; -- int timeSecs = getModtime(f.lastModified()); -- if (keepModtime && timeSecs != Constants.NO_MODTIME) { -- this.modtime = timeSecs; -- } else if (latestModtime && timeSecs > pkg.default_modtime) { -- pkg.default_modtime = timeSecs; -- } -- } -- InFile(JarFile jf, JarEntry je) { -- this.name = Utils.getJarEntryName(je.getName()); -- this.f = null; -- this.jf = jf; -- this.je = je; -- int timeSecs = getModtime(je.getTime()); -- if (keepModtime && timeSecs != Constants.NO_MODTIME) { -- this.modtime = timeSecs; -- } else if (latestModtime && timeSecs > pkg.default_modtime) { -- pkg.default_modtime = timeSecs; -- } -- if (keepDeflateHint && je.getMethod() == JarEntry.DEFLATED) { -- options |= Constants.FO_DEFLATE_HINT; -- } -- } -- InFile(JarEntry je) { -- this(null, je); -- } -- long getInputLength() { -- long len = (je != null)? je.getSize(): f.length(); -- assert(len >= 0) : this+".len="+len; -- // Bump size by pathname length and modtime/def-hint bytes. -- return Math.max(0, len) + name.length() + 5; -- } -- int getModtime(long timeMillis) { -- // Convert milliseconds to seconds. -- long seconds = (timeMillis+500) / 1000; -- if ((int)seconds == seconds) { -- return (int)seconds; -- } else { -- Utils.log.warning("overflow in modtime for "+f); -- return Constants.NO_MODTIME; -- } -- } -- void copyTo(Package.File file) { -- if (modtime != Constants.NO_MODTIME) -- file.modtime = modtime; -- file.options |= options; -- } -- InputStream getInputStream() throws IOException { -- if (jf != null) -- return jf.getInputStream(je); -- else -- return new FileInputStream(f); -- } -+ class InFile { -+ final String name; -+ final JarFile jf; -+ final JarEntry je; -+ final File f; -+ int modtime = Constants.NO_MODTIME; -+ int options; -+ InFile(String name) { -+ this.name = Utils.getJarEntryName(name); -+ this.f = new File(name); -+ this.jf = null; -+ this.je = null; -+ int timeSecs = getModtime(f.lastModified()); -+ if (keepModtime && timeSecs != Constants.NO_MODTIME) { -+ this.modtime = timeSecs; -+ } else if (latestModtime && timeSecs > pkg.default_modtime) { -+ pkg.default_modtime = timeSecs; -+ } -+ } -+ InFile(JarFile jf, JarEntry je) { -+ this.name = Utils.getJarEntryName(je.getName()); -+ this.f = null; -+ this.jf = jf; -+ this.je = je; -+ int timeSecs = getModtime(je.getTime()); -+ if (keepModtime && timeSecs != Constants.NO_MODTIME) { -+ this.modtime = timeSecs; -+ } else if (latestModtime && timeSecs > pkg.default_modtime) { -+ pkg.default_modtime = timeSecs; -+ } -+ if (keepDeflateHint && je.getMethod() == JarEntry.DEFLATED) { -+ options |= Constants.FO_DEFLATE_HINT; -+ } -+ } -+ InFile(JarEntry je) { -+ this(null, je); -+ } -+ long getInputLength() { -+ long len = (je != null)? je.getSize(): f.length(); -+ assert(len >= 0) : this+".len="+len; -+ // Bump size by pathname length and modtime/def-hint bytes. -+ return Math.max(0, len) + name.length() + 5; -+ } -+ int getModtime(long timeMillis) { -+ // Convert milliseconds to seconds. -+ long seconds = (timeMillis+500) / 1000; -+ if ((int)seconds == seconds) { -+ return (int)seconds; -+ } else { -+ Utils.log.warning("overflow in modtime for "+f); -+ return Constants.NO_MODTIME; -+ } -+ } -+ void copyTo(Package.File file) { -+ if (modtime != Constants.NO_MODTIME) -+ file.modtime = modtime; -+ file.options |= options; -+ } -+ InputStream getInputStream() throws IOException { -+ if (jf != null) -+ return jf.getInputStream(je); -+ else -+ return new FileInputStream(f); -+ } - -- public String toString() { -- return name; -- } -- } -+ public String toString() { -+ return name; -+ } -+ } - -- private int nread = 0; // used only if (verbose > 0) -- private void noteRead(InFile f) { -- nread++; -- if (verbose > 2) -- Utils.log.fine("...read "+f.name); -- if (verbose > 0 && (nread % 1000) == 0) -- Utils.log.info("Have read "+nread+" files..."); -- } -+ private int nread = 0; // used only if (verbose > 0) -+ private void noteRead(InFile f) { -+ nread++; -+ if (verbose > 2) -+ Utils.log.fine("...read "+f.name); -+ if (verbose > 0 && (nread % 1000) == 0) -+ Utils.log.info("Have read "+nread+" files..."); -+ } - -- void run(JarInputStream in, OutputStream out) throws IOException { -- // First thing we do is get the manifest, as JIS does -- // not provide the Manifest as an entry. -- if (in.getManifest() != null) { -- ByteArrayOutputStream tmp = new ByteArrayOutputStream(); -- in.getManifest().write(tmp); -- InputStream tmpIn = new ByteArrayInputStream(tmp.toByteArray()); -- pkg.addFile(readFile(JarFile.MANIFEST_NAME, tmpIn)); -- } -- for (JarEntry je; (je = in.getNextJarEntry()) != null; ) { -- InFile inFile = new InFile(je); -+ void run(JarInputStream in, OutputStream out) throws IOException { -+ // First thing we do is get the manifest, as JIS does -+ // not provide the Manifest as an entry. -+ if (in.getManifest() != null) { -+ ByteArrayOutputStream tmp = new ByteArrayOutputStream(); -+ in.getManifest().write(tmp); -+ InputStream tmpIn = new ByteArrayInputStream(tmp.toByteArray()); -+ pkg.addFile(readFile(JarFile.MANIFEST_NAME, tmpIn)); -+ } -+ for (JarEntry je; (je = in.getNextJarEntry()) != null; ) { -+ InFile inFile = new InFile(je); - -- String name = inFile.name; -- Package.File bits = readFile(name, in); -- Package.File file = null; -- // (5078608) : discount the resource files in META-INF -- // from segment computation. -- long inflen = (isMetaInfFile(name)) ? 0L : -- inFile.getInputLength(); -+ String name = inFile.name; -+ Package.File bits = readFile(name, in); -+ Package.File file = null; -+ // (5078608) : discount the resource files in META-INF -+ // from segment computation. -+ long inflen = (isMetaInfFile(name)) ? 0L : -+ inFile.getInputLength(); - -- if ((segmentSize += inflen) > segmentLimit) { -- segmentSize -= inflen; -- int nextCount = -1; // don't know; it's a stream -- flushPartial(out, nextCount); -- } -- if (verbose > 1) -- Utils.log.fine("Reading " + name); -+ if ((segmentSize += inflen) > segmentLimit) { -+ segmentSize -= inflen; -+ int nextCount = -1; // don't know; it's a stream -+ flushPartial(out, nextCount); -+ } -+ if (verbose > 1) -+ Utils.log.fine("Reading " + name); - -- assert(je.isDirectory() == name.endsWith("/")); -+ assert(je.isDirectory() == name.endsWith("/")); - -- if (isClassFile(name)) { -- file = readClass(name, bits.getInputStream()); -- } -- if (file == null) { -- file = bits; -- pkg.addFile(file); -- } -- inFile.copyTo(file); -- noteRead(inFile); -- } -- flushAll(out); -- } -+ if (isClassFile(name)) { -+ file = readClass(name, bits.getInputStream()); -+ } -+ if (file == null) { -+ file = bits; -+ pkg.addFile(file); -+ } -+ inFile.copyTo(file); -+ noteRead(inFile); -+ } -+ flushAll(out); -+ } - -- void run(JarFile in, OutputStream out) throws IOException { -- List inFiles = scanJar(in); -+ void run(JarFile in, OutputStream out) throws IOException { -+ List inFiles = scanJar(in); - -- if (verbose > 0) -- Utils.log.info("Reading " + inFiles.size() + " files..."); -+ if (verbose > 0) -+ Utils.log.info("Reading " + inFiles.size() + " files..."); - -- int numDone = 0; -- for (Iterator i = inFiles.iterator(); i.hasNext(); ) { -- InFile inFile = (InFile) i.next(); -- String name = inFile.name; -- // (5078608) : discount the resource files completely from segmenting -- long inflen = (isMetaInfFile(name)) ? 0L : -- inFile.getInputLength() ; -- if ((segmentSize += inflen) > segmentLimit) { -- segmentSize -= inflen; -- // Estimate number of remaining segments: -- float filesDone = numDone+1; -- float segsDone = segmentCount+1; -- float filesToDo = inFiles.size() - filesDone; -- float segsToDo = filesToDo * (segsDone/filesDone); -- if (verbose > 1) -- Utils.log.fine("Estimated segments to do: "+segsToDo); -- flushPartial(out, (int) Math.ceil(segsToDo)); -- } -- InputStream strm = inFile.getInputStream(); -- if (verbose > 1) -- Utils.log.fine("Reading " + name); -- Package.File file = null; -- if (isClassFile(name)) { -- file = readClass(name, strm); -- if (file == null) { -- strm.close(); -- strm = inFile.getInputStream(); -- } -- } -- if (file == null) { -- file = readFile(name, strm); -- pkg.addFile(file); -- } -- inFile.copyTo(file); -- strm.close(); // tidy up -- noteRead(inFile); -- numDone += 1; -- } -- flushAll(out); -- } -+ int numDone = 0; -+ for (Iterator i = inFiles.iterator(); i.hasNext(); ) { -+ InFile inFile = (InFile) i.next(); -+ String name = inFile.name; -+ // (5078608) : discount the resource files completely from segmenting -+ long inflen = (isMetaInfFile(name)) ? 0L : -+ inFile.getInputLength() ; -+ if ((segmentSize += inflen) > segmentLimit) { -+ segmentSize -= inflen; -+ // Estimate number of remaining segments: -+ float filesDone = numDone+1; -+ float segsDone = segmentCount+1; -+ float filesToDo = inFiles.size() - filesDone; -+ float segsToDo = filesToDo * (segsDone/filesDone); -+ if (verbose > 1) -+ Utils.log.fine("Estimated segments to do: "+segsToDo); -+ flushPartial(out, (int) Math.ceil(segsToDo)); -+ } -+ InputStream strm = inFile.getInputStream(); -+ if (verbose > 1) -+ Utils.log.fine("Reading " + name); -+ Package.File file = null; -+ if (isClassFile(name)) { -+ file = readClass(name, strm); -+ if (file == null) { -+ strm.close(); -+ strm = inFile.getInputStream(); -+ } -+ } -+ if (file == null) { -+ file = readFile(name, strm); -+ pkg.addFile(file); -+ } -+ inFile.copyTo(file); -+ strm.close(); // tidy up -+ noteRead(inFile); -+ numDone += 1; -+ } -+ flushAll(out); -+ } - -- Package.File readClass(String fname, InputStream in) throws IOException { -- Package.Class cls = pkg.new Class(fname); -- in = new BufferedInputStream(in); -- ClassReader reader = new ClassReader(cls, in); -- reader.setAttrDefs(attrDefs); -- reader.setAttrCommands(attrCommands); -- reader.unknownAttrCommand = unknownAttrCommand; -- try { -- reader.read(); -- } catch (Attribute.FormatException ee) { -- // He passed up the category to us in layout. -- if (ee.layout.equals(Pack200.Packer.PASS)) { -- Utils.log.warning("Passing class file uncompressed due to unrecognized attribute: "+fname); -- Utils.log.info(ee.toString()); -- return null; -- } -- // Otherwise, it must be an error. -- throw ee; -- } -- pkg.addClass(cls); -- return cls.file; -- } -+ Package.File readClass(String fname, InputStream in) throws IOException { -+ Package.Class cls = pkg.new Class(fname); -+ in = new BufferedInputStream(in); -+ ClassReader reader = new ClassReader(cls, in); -+ reader.setAttrDefs(attrDefs); -+ reader.setAttrCommands(attrCommands); -+ reader.unknownAttrCommand = unknownAttrCommand; -+ try { -+ reader.read(); -+ } catch (Attribute.FormatException ee) { -+ // He passed up the category to us in layout. -+ if (ee.layout.equals(Pack200.Packer.PASS)) { -+ Utils.log.warning("Passing class file uncompressed due to unrecognized attribute: "+fname); -+ Utils.log.info(ee.toString()); -+ return null; -+ } -+ // Otherwise, it must be an error. -+ throw ee; -+ } -+ pkg.addClass(cls); -+ return cls.file; -+ } - -- // Read raw data. -- Package.File readFile(String fname, InputStream in) throws IOException { -+ // Read raw data. -+ Package.File readFile(String fname, InputStream in) throws IOException { - -- Package.File file = pkg.new File(fname); -- file.readFrom(in); -- if (file.isDirectory() && file.getFileLength() != 0) -- throw new IllegalArgumentException("Non-empty directory: "+file.getFileName()); -- return file; -- } -+ Package.File file = pkg.new File(fname); -+ file.readFrom(in); -+ if (file.isDirectory() && file.getFileLength() != 0) -+ throw new IllegalArgumentException("Non-empty directory: "+file.getFileName()); -+ return file; -+ } - -- void flushPartial(OutputStream out, int nextCount) throws IOException { -- if (pkg.files.size() == 0 && pkg.classes.size() == 0) { -- return; // do not flush an empty segment -- } -- flushPackage(out, Math.max(1, nextCount)); -- _props.setInteger(Pack200.Packer.PROGRESS, 25); -- // In case there will be another segment: -- makeNextPackage(); -- segmentCount += 1; -- segmentTotalSize += segmentSize; -- segmentSize = 0; -- } -+ void flushPartial(OutputStream out, int nextCount) throws IOException { -+ if (pkg.files.size() == 0 && pkg.classes.size() == 0) { -+ return; // do not flush an empty segment -+ } -+ flushPackage(out, Math.max(1, nextCount)); -+ _props.setInteger(Pack200.Packer.PROGRESS, 25); -+ // In case there will be another segment: -+ makeNextPackage(); -+ segmentCount += 1; -+ segmentTotalSize += segmentSize; -+ segmentSize = 0; -+ } - -- void flushAll(OutputStream out) throws IOException { -- _props.setInteger(Pack200.Packer.PROGRESS, 50); -- flushPackage(out, 0); -- out.flush(); -- _props.setInteger(Pack200.Packer.PROGRESS, 100); -- segmentCount += 1; -- segmentTotalSize += segmentSize; -- segmentSize = 0; -- if (verbose > 0 && segmentCount > 1) { -- Utils.log.info("Transmitted " -- +segmentTotalSize+" input bytes in " -- +segmentCount+" segments totaling " -- +totalOutputSize+" bytes"); -- } -- } -+ void flushAll(OutputStream out) throws IOException { -+ _props.setInteger(Pack200.Packer.PROGRESS, 50); -+ flushPackage(out, 0); -+ out.flush(); -+ _props.setInteger(Pack200.Packer.PROGRESS, 100); -+ segmentCount += 1; -+ segmentTotalSize += segmentSize; -+ segmentSize = 0; -+ if (verbose > 0 && segmentCount > 1) { -+ Utils.log.info("Transmitted " -+ +segmentTotalSize+" input bytes in " -+ +segmentCount+" segments totaling " -+ +totalOutputSize+" bytes"); -+ } -+ } - - -- /** Write all information in the current package segment -- * to the output stream. -- */ -- void flushPackage(OutputStream out, int nextCount) throws IOException { -- int nfiles = pkg.files.size(); -- if (!keepFileOrder) { -- // Keeping the order of classes costs about 1% -- // Keeping the order of all files costs something more. -- if (verbose > 1) Utils.log.fine("Reordering files."); -- boolean stripDirectories = true; -- pkg.reorderFiles(keepClassOrder, stripDirectories); -- } else { -- // Package builder must have created a stub for each class. -- assert(pkg.files.containsAll(pkg.getClassStubs())); -- // Order of stubs in file list must agree with classes. -- List res = pkg.files; -- assert((res = new ArrayList(pkg.files)) -- .retainAll(pkg.getClassStubs()) || true); -- assert(res.equals(pkg.getClassStubs())); -- } -- pkg.trimStubs(); -+ /** Write all information in the current package segment -+ * to the output stream. -+ */ -+ void flushPackage(OutputStream out, int nextCount) throws IOException { -+ int nfiles = pkg.files.size(); -+ if (!keepFileOrder) { -+ // Keeping the order of classes costs about 1% -+ // Keeping the order of all files costs something more. -+ if (verbose > 1) Utils.log.fine("Reordering files."); -+ boolean stripDirectories = true; -+ pkg.reorderFiles(keepClassOrder, stripDirectories); -+ } else { -+ // Package builder must have created a stub for each class. -+ assert(pkg.files.containsAll(pkg.getClassStubs())); -+ // Order of stubs in file list must agree with classes. -+ List res = pkg.files; -+ assert((res = new ArrayList(pkg.files)) -+ .retainAll(pkg.getClassStubs()) || true); -+ assert(res.equals(pkg.getClassStubs())); -+ } -+ pkg.trimStubs(); - -- // Do some stripping, maybe. -- if (_props.getBoolean(Utils.COM_PREFIX+"strip.debug")) pkg.stripAttributeKind("Debug"); -- if (_props.getBoolean(Utils.COM_PREFIX+"strip.compile")) pkg.stripAttributeKind("Compile"); -- if (_props.getBoolean(Utils.COM_PREFIX+"strip.constants")) pkg.stripAttributeKind("Constant"); -- if (_props.getBoolean(Utils.COM_PREFIX+"strip.exceptions")) pkg.stripAttributeKind("Exceptions"); -- if (_props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses"); -+ // Do some stripping, maybe. -+ if (_props.getBoolean(Utils.COM_PREFIX+"strip.debug")) pkg.stripAttributeKind("Debug"); -+ if (_props.getBoolean(Utils.COM_PREFIX+"strip.compile")) pkg.stripAttributeKind("Compile"); -+ if (_props.getBoolean(Utils.COM_PREFIX+"strip.constants")) pkg.stripAttributeKind("Constant"); -+ if (_props.getBoolean(Utils.COM_PREFIX+"strip.exceptions")) pkg.stripAttributeKind("Exceptions"); -+ if (_props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses"); - -- // Must choose an archive version; PackageWriter does not. -- if (pkg.package_majver <= 0) pkg.choosePackageVersion(); -+ // Must choose an archive version; PackageWriter does not. -+ if (pkg.package_majver <= 0) pkg.choosePackageVersion(); - -- PackageWriter pw = new PackageWriter(pkg, out); -- pw.archiveNextCount = nextCount; -- pw.write(); -- out.flush(); -- if (verbose > 0) { -- long outSize = pw.archiveSize0+pw.archiveSize1; -- totalOutputSize += outSize; -- long inSize = segmentSize; -- Utils.log.info("Transmitted " -- +nfiles+" files of " -- +inSize+" input bytes in a segment of " -- +outSize+" bytes"); -- } -- } -+ PackageWriter pw = new PackageWriter(pkg, out); -+ pw.archiveNextCount = nextCount; -+ pw.write(); -+ out.flush(); -+ if (verbose > 0) { -+ long outSize = pw.archiveSize0+pw.archiveSize1; -+ totalOutputSize += outSize; -+ long inSize = segmentSize; -+ Utils.log.info("Transmitted " -+ +nfiles+" files of " -+ +inSize+" input bytes in a segment of " -+ +outSize+" bytes"); -+ } -+ } - -- List scanJar(JarFile jf) throws IOException { -- // Collect jar entries, preserving order. -- List inFiles = new ArrayList(); -- for (Enumeration e = jf.entries(); e.hasMoreElements(); ) { -- JarEntry je = (JarEntry) e.nextElement(); -- InFile inFile = new InFile(jf, je); -- assert(je.isDirectory() == inFile.name.endsWith("/")); -- inFiles.add(inFile); -- } -- return inFiles; -- } -+ List scanJar(JarFile jf) throws IOException { -+ // Collect jar entries, preserving order. -+ List inFiles = new ArrayList(); -+ for (Enumeration e = jf.entries(); e.hasMoreElements(); ) { -+ JarEntry je = (JarEntry) e.nextElement(); -+ InFile inFile = new InFile(jf, je); -+ assert(je.isDirectory() == inFile.name.endsWith("/")); -+ inFiles.add(inFile); -+ } -+ return inFiles; -+ } - } - } -+ -+ -+ -+ -+ -+ -+ -diff --git a/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java b/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java ---- jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java -+++ jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -41,53 +41,53 @@ import java.beans.PropertyChangeEvent; - - - public class UnpackerImpl implements Pack200.Unpacker { -- -- -+ -+ - /** - * Register a listener for changes to options. - * @param listener An object to be invoked when a property is changed. - */ - public void addPropertyChangeListener(PropertyChangeListener listener) { -- _props.addListener(listener); -+ _props.addListener(listener); - } -- -- -+ -+ - /** - * Remove a listener for the PropertyChange event. - * @param listener The PropertyChange listener to be removed. - */ - public void removePropertyChangeListener(PropertyChangeListener listener) { -- _props.removeListener(listener); -+ _props.removeListener(listener); - } -- -+ - public UnpackerImpl() { -- _props = new PropMap(); -- //_props.getProperty() consults defaultProps invisibly. -- //_props.putAll(defaultProps); -+ _props = new PropMap(); -+ //_props.getProperty() consults defaultProps invisibly. -+ //_props.putAll(defaultProps); - } -- -+ - // Private stuff. - final PropMap _props; - -- -+ - /** - * Get the set of options for the pack and unpack engines. - * @return A sorted association of option key strings to option values. - */ - public SortedMap properties() { -- return _props; -+ return _props; - } -- -+ - // Back-pointer to NativeUnpacker, when active. - Object _nunp; -- -- -+ -+ - public String toString() { -- return Utils.getVersionString(); -+ return Utils.getVersionString(); - } -- -+ - //Driver routines -- -+ - // The unpack worker... - /** - * Takes a packed-stream InputStream, and writes to a JarOutputStream. Internally -@@ -99,36 +99,36 @@ public class UnpackerImpl implements Pac - * @param out a JarOutputStream. - * @exception IOException if an error is encountered. - */ -- public void unpack(InputStream in0, JarOutputStream out) throws IOException { -- assert(Utils.currentInstance.get() == null); -- TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : -- TimeZone.getDefault(); -- -- try { -- Utils.currentInstance.set(this); -- if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); -- final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -- BufferedInputStream in = new BufferedInputStream(in0); -- if (Utils.isJarMagic(Utils.readMagic(in))) { -- if (verbose > 0) -- Utils.log.info("Copying unpacked JAR file..."); -- Utils.copyJarFile(new JarInputStream(in), out); -- } else if (_props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) { -- (new DoUnpack()).run(in, out); -- in.close(); -- Utils.markJarFile(out); -- } else { -- (new NativeUnpack(this)).run(in, out); -- in.close(); -- Utils.markJarFile(out); -- } -- } finally { -- _nunp = null; -- Utils.currentInstance.set(null); -- if (tz != null) TimeZone.setDefault(tz); -- } -+ public synchronized void unpack(InputStream in0, JarOutputStream out) throws IOException { -+ assert(Utils.currentInstance.get() == null); -+ TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : -+ TimeZone.getDefault(); -+ -+ try { -+ Utils.currentInstance.set(this); -+ if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC")); -+ final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -+ BufferedInputStream in = new BufferedInputStream(in0); -+ if (Utils.isJarMagic(Utils.readMagic(in))) { -+ if (verbose > 0) -+ Utils.log.info("Copying unpacked JAR file..."); -+ Utils.copyJarFile(new JarInputStream(in), out); -+ } else if (_props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) { -+ (new DoUnpack()).run(in, out); -+ in.close(); -+ Utils.markJarFile(out); -+ } else { -+ (new NativeUnpack(this)).run(in, out); -+ in.close(); -+ Utils.markJarFile(out); -+ } -+ } finally { -+ _nunp = null; -+ Utils.currentInstance.set(null); -+ if (tz != null) TimeZone.setDefault(tz); -+ } - } -- -+ - /** - * Takes an input File containing the pack file, and generates a JarOutputStream. - * <p> -@@ -137,121 +137,121 @@ public class UnpackerImpl implements Pac - * @param out a JarOutputStream. - * @exception IOException if an error is encountered. - */ -- public void unpack(File in, JarOutputStream out) throws IOException { -- // Use the stream-based implementation. -- // %%% Reconsider if native unpacker learns to memory-map the file. -- FileInputStream instr = new FileInputStream(in); -- unpack(instr, out); -- if (_props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) { -- in.delete(); -- } -+ public synchronized void unpack(File in, JarOutputStream out) throws IOException { -+ // Use the stream-based implementation. -+ // %%% Reconsider if native unpacker learns to memory-map the file. -+ FileInputStream instr = new FileInputStream(in); -+ unpack(instr, out); -+ if (_props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) { -+ in.delete(); -+ } - } -- -+ - private class DoUnpack { -- final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -- -- { -- _props.setInteger(Pack200.Unpacker.PROGRESS, 0); -- } -- -- // Here's where the bits are read from disk: -- final Package pkg = new Package(); -- -- final boolean keepModtime -- = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP)); -- final boolean keepDeflateHint -- = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP)); -- final int modtime; -- final boolean deflateHint; -- { -- if (!keepModtime) { -- modtime = _props.getTime(Utils.UNPACK_MODIFICATION_TIME); -- } else { -- modtime = pkg.default_modtime; -- } -- -- deflateHint = (keepDeflateHint) ? false : -- _props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT); -- } -- -- // Checksum apparatus. -- final CRC32 crc = new CRC32(); -- final ByteArrayOutputStream bufOut = new ByteArrayOutputStream(); -- final OutputStream crcOut = new CheckedOutputStream(bufOut, crc); -- -- public void run(BufferedInputStream in, JarOutputStream out) throws IOException { -- if (verbose > 0) { -- _props.list(System.out); -- } -- for (int seg = 1; ; seg++) { -- unpackSegment(in, out); -- -- // Try to get another segment. -- if (!Utils.isPackMagic(Utils.readMagic(in))) break; -- if (verbose > 0) -- Utils.log.info("Finished segment #"+seg); -- } -- } -- -- private void unpackSegment(InputStream in, JarOutputStream out) throws IOException { -- _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0"); -- // Process the output directory or jar output. -- new PackageReader(pkg, in).read(); -- -- if (_props.getBoolean("unpack.strip.debug")) pkg.stripAttributeKind("Debug"); -- if (_props.getBoolean("unpack.strip.compile")) pkg.stripAttributeKind("Compile"); -- _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50"); -- pkg.ensureAllClassFiles(); -- // Now write out the files. -- HashSet classesToWrite = new HashSet(pkg.getClasses()); -- for (Iterator i = pkg.getFiles().iterator(); i.hasNext(); ) { -- Package.File file = (Package.File) i.next(); -- String name = file.nameString; -- JarEntry je = new JarEntry(Utils.getJarEntryName(name)); -- boolean deflate; -- -- deflate = (keepDeflateHint) ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) || -- ((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0)) : -- deflateHint; -- -- boolean needCRC = !deflate; // STORE mode requires CRC -- -- if (needCRC) crc.reset(); -- bufOut.reset(); -- if (file.isClassStub()) { -- Package.Class cls = file.getStubClass(); -- assert(cls != null); -- new ClassWriter(cls, needCRC ? crcOut : bufOut).write(); -- classesToWrite.remove(cls); // for an error check -- } else { -- // collect data & maybe CRC -- file.writeTo(needCRC ? crcOut : bufOut); -- } -- je.setMethod(deflate ? JarEntry.DEFLATED : JarEntry.STORED); -- if (needCRC) { -- if (verbose > 0) -- Utils.log.info("stored size="+bufOut.size()+" and crc="+crc.getValue()); -- -- je.setMethod(JarEntry.STORED); -- je.setSize(bufOut.size()); -- je.setCrc(crc.getValue()); -- } -- if (keepModtime) { -- je.setTime(file.modtime); -- // Convert back to milliseconds -- je.setTime((long)file.modtime * 1000); -- } else { -- je.setTime((long)modtime * 1000); -- } -- out.putNextEntry(je); -- bufOut.writeTo(out); -- out.closeEntry(); -- if (verbose > 0) -- Utils.log.info("Writing "+Utils.zeString((ZipEntry)je)); -- } -- assert(classesToWrite.isEmpty()); -- _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100"); -- pkg.reset(); // reset for the next segment, if any -- } -+ final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE); -+ -+ { -+ _props.setInteger(Pack200.Unpacker.PROGRESS, 0); -+ } -+ -+ // Here's where the bits are read from disk: -+ final Package pkg = new Package(); -+ -+ final boolean keepModtime -+ = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP)); -+ final boolean keepDeflateHint -+ = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP)); -+ final int modtime; -+ final boolean deflateHint; -+ { -+ if (!keepModtime) { -+ modtime = _props.getTime(Utils.UNPACK_MODIFICATION_TIME); -+ } else { -+ modtime = pkg.default_modtime; -+ } -+ -+ deflateHint = (keepDeflateHint) ? false : -+ _props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT); -+ } -+ -+ // Checksum apparatus. -+ final CRC32 crc = new CRC32(); -+ final ByteArrayOutputStream bufOut = new ByteArrayOutputStream(); -+ final OutputStream crcOut = new CheckedOutputStream(bufOut, crc); -+ -+ public void run(BufferedInputStream in, JarOutputStream out) throws IOException { -+ if (verbose > 0) { -+ _props.list(System.out); -+ } -+ for (int seg = 1; ; seg++) { -+ unpackSegment(in, out); -+ -+ // Try to get another segment. -+ if (!Utils.isPackMagic(Utils.readMagic(in))) break; -+ if (verbose > 0) -+ Utils.log.info("Finished segment #"+seg); -+ } -+ } -+ -+ private void unpackSegment(InputStream in, JarOutputStream out) throws IOException { -+ _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0"); -+ // Process the output directory or jar output. -+ new PackageReader(pkg, in).read(); -+ -+ if (_props.getBoolean("unpack.strip.debug")) pkg.stripAttributeKind("Debug"); -+ if (_props.getBoolean("unpack.strip.compile")) pkg.stripAttributeKind("Compile"); -+ _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50"); -+ pkg.ensureAllClassFiles(); -+ // Now write out the files. -+ HashSet classesToWrite = new HashSet(pkg.getClasses()); -+ for (Iterator i = pkg.getFiles().iterator(); i.hasNext(); ) { -+ Package.File file = (Package.File) i.next(); -+ String name = file.nameString; -+ JarEntry je = new JarEntry(Utils.getJarEntryName(name)); -+ boolean deflate; -+ -+ deflate = (keepDeflateHint) ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) || -+ ((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0)) : -+ deflateHint; -+ -+ boolean needCRC = !deflate; // STORE mode requires CRC -+ -+ if (needCRC) crc.reset(); -+ bufOut.reset(); -+ if (file.isClassStub()) { -+ Package.Class cls = file.getStubClass(); -+ assert(cls != null); -+ new ClassWriter(cls, needCRC ? crcOut : bufOut).write(); -+ classesToWrite.remove(cls); // for an error check -+ } else { -+ // collect data & maybe CRC -+ file.writeTo(needCRC ? crcOut : bufOut); -+ } -+ je.setMethod(deflate ? JarEntry.DEFLATED : JarEntry.STORED); -+ if (needCRC) { -+ if (verbose > 0) -+ Utils.log.info("stored size="+bufOut.size()+" and crc="+crc.getValue()); -+ -+ je.setMethod(JarEntry.STORED); -+ je.setSize(bufOut.size()); -+ je.setCrc(crc.getValue()); -+ } -+ if (keepModtime) { -+ je.setTime(file.modtime); -+ // Convert back to milliseconds -+ je.setTime((long)file.modtime * 1000); -+ } else { -+ je.setTime((long)modtime * 1000); -+ } -+ out.putNextEntry(je); -+ bufOut.writeTo(out); -+ out.closeEntry(); -+ if (verbose > 0) -+ Utils.log.info("Writing "+Utils.zeString((ZipEntry)je)); -+ } -+ assert(classesToWrite.isEmpty()); -+ _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100"); -+ pkg.reset(); // reset for the next segment, if any -+ } - } - } -diff --git a/src/share/native/com/sun/java/util/jar/pack/bands.cpp b/src/share/native/com/sun/java/util/jar/pack/bands.cpp ---- jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp -+++ jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -81,11 +81,11 @@ void band::readData(int expectedLength) - assert(defc->B() > 1 && defc->L() > 0); - // must have already read from previous band: - assert(bn >= BAND_LIMIT || bn <= 0 -- || bn == e_cp_Utf8_big_chars -- || endsWith(name, "_lo") // preceded by _hi conditional band -- || bn == e_file_options // preceded by conditional band -- || u->rp == u->all_bands[bn-1].maxRP() -- || u->all_bands[bn-1].defc == null); -+ || bn == e_cp_Utf8_big_chars -+ || endsWith(name, "_lo") // preceded by _hi conditional band -+ || bn == e_file_options // preceded by conditional band -+ || u->rp == u->all_bands[bn-1].maxRP() -+ || u->all_bands[bn-1].defc == null); - - value_stream xvs; - coding* valc = defc; -@@ -136,7 +136,7 @@ void band::readData(int expectedLength) - - #ifndef PRODUCT - printcr(3,"readFrom %s at %p [%d values, %d bytes, cp=%d/%d]", -- (name?name:"(band)"), minRP(), length, size(), cp1, cp2); -+ (name?name:"(band)"), minRP(), length, size(), cp1, cp2); - if (u->verbose_bands || u->verbose >= 4) dump(); - - if (ix != null && u->verbose != 0 && length > 0) { -@@ -187,10 +187,14 @@ void band::setIndexByTag(byte tag) { - - entry* band::getRefCommon(cpindex* ix_, bool nullOKwithCaller) { - CHECK_0; -+ if (ix_ == NULL) { -+ abort("no index"); -+ return NULL; -+ } - assert(ix_->ixTag == ixTag -- || (ixTag == CONSTANT_Literal -- && ix_->ixTag >= CONSTANT_Integer -- && ix_->ixTag <= CONSTANT_String)); -+ || (ixTag == CONSTANT_Literal -+ && ix_->ixTag >= CONSTANT_Integer -+ && ix_->ixTag <= CONSTANT_String)); - int n = vs[0].getInt() - nullOK; - // Note: band-local nullOK means null encodes as 0. - // But nullOKwithCaller means caller is willing to tolerate a null. -@@ -245,9 +249,9 @@ int band::getIntCount(int tag) { - hist0 = U_NEW(int, (HIST0_MAX - HIST0_MIN)+1); - CHECK_0; - for (int k = length; k > 0; k--) { -- int x = vs[0].getInt(); -- if (x >= HIST0_MIN && x <= HIST0_MAX) -- hist0[x - HIST0_MIN] += 1; -+ int x = vs[0].getInt(); -+ if (x >= HIST0_MIN && x <= HIST0_MAX) -+ hist0[x - HIST0_MIN] += 1; - } - rewind(); - } -@@ -262,7 +266,7 @@ int band::getIntCount(int tag) { - } - - #define INDEX_INIT(tag, nullOK, subindex) \ -- ((tag) + (subindex)*SUBINDEX_BIT + (nullOK)*256) -+ ((tag) + (subindex)*SUBINDEX_BIT + (nullOK)*256) - - #define INDEX(tag) INDEX_INIT(tag, 0, 0) - #define NULL_OR_INDEX(tag) INDEX_INIT(tag, 1, 0) -@@ -437,13 +441,13 @@ const band_init all_band_inits[] = { - {0} - }; - #define NUM_BAND_INITS \ -- (sizeof(all_band_inits)/sizeof(all_band_inits[0])) -+ (sizeof(all_band_inits)/sizeof(all_band_inits[0])) - - band* band::makeBands(unpacker* u) { - band* all_bands = U_NEW(band, BAND_LIMIT); - for (int i = 0; i < BAND_LIMIT; i++) { - assert((byte*)&all_band_inits[i+1] -- < (byte*)all_band_inits+sizeof(all_band_inits)); -+ < (byte*)all_band_inits+sizeof(all_band_inits)); - const band_init& bi = all_band_inits[i]; - band& b = all_bands[i]; - coding* defc = coding::findBySpec(bi.defc); -@@ -472,3 +476,5 @@ void band::initIndexes(unpacker* u) { - } - } - } -+ -+ -diff --git a/src/share/native/com/sun/java/util/jar/pack/bands.h b/src/share/native/com/sun/java/util/jar/pack/bands.h ---- jdk/src/share/native/com/sun/java/util/jar/pack/bands.h -+++ jdk/src/share/native/com/sun/java/util/jar/pack/bands.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -22,7 +22,7 @@ - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -- -+ - // -*- C++ -*- - struct entry; - struct cpindex; -@@ -50,7 +50,7 @@ struct band { - - // properties for attribute layout elements: - byte le_kind; // EK_XXX -- byte le_bci; // 0,EK_BCI,EK_BCD,EK_BCO -+ byte le_bci; // 0,EK_BCI,EK_BCD,EK_BCO - byte le_back; // ==EF_BACK - byte le_len; // 0,1,2,4 (size in classfile), or call addr - band** le_body; // body of repl, union, call (null-terminated) -@@ -101,8 +101,8 @@ struct band { - - int getByte() { assert(ix == null); return vs[0].getByte(); } - int getInt() { assert(ix == null); return vs[0].getInt(); } -- entry* getRefN() { assert(ix != null); return getRefCommon(ix, true); } -- entry* getRef() { assert(ix != null); return getRefCommon(ix, false); } -+ entry* getRefN() { return getRefCommon(ix, true); } -+ entry* getRef() { return getRefCommon(ix, false); } - entry* getRefUsing(cpindex* ix2) - { assert(ix == null); return getRefCommon(ix2, true); } - entry* getRefCommon(cpindex* ix, bool nullOK); -diff --git a/src/share/native/com/sun/java/util/jar/pack/defines.h b/src/share/native/com/sun/java/util/jar/pack/defines.h ---- jdk/src/share/native/com/sun/java/util/jar/pack/defines.h -+++ jdk/src/share/native/com/sun/java/util/jar/pack/defines.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -22,10 +22,10 @@ - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -- -+ - // random definitions - --#ifdef _MSC_VER -+#ifdef _MSC_VER - #include <windows.h> - #include <winuser.h> - #else -@@ -94,15 +94,15 @@ typedef unsigned int uLong; // Historica - #else - typedef unsigned long uLong; - #endif --#ifdef _MSC_VER --typedef LONGLONG jlong; --typedef DWORDLONG julong; --#define MKDIR(dir) mkdir(dir) --#define getpid() _getpid() --#define PATH_MAX MAX_PATH --#define dup2(a,b) _dup2(a,b) -+#ifdef _MSC_VER -+typedef LONGLONG jlong; -+typedef DWORDLONG julong; -+#define MKDIR(dir) mkdir(dir) -+#define getpid() _getpid() -+#define PATH_MAX MAX_PATH -+#define dup2(a,b) _dup2(a,b) - #define strcasecmp(s1, s2) _stricmp(s1,s2) --#define tempname _tempname -+#define tempname _tempname - #define sleep Sleep - #else - typedef signed char byte; -@@ -123,37 +123,40 @@ enum { false, true }; - - #define null (0) - --#ifndef __sparc -+#ifndef __sparc - #define intptr_t jlong - #endif - - #define ptrlowbits(x) ((int) (intptr_t)(x)) - -+/* Back and forth from jlong to pointer */ -+#define ptr2jlong(x) ((jlong)(size_t)(void*)(x)) -+#define jlong2ptr(x) ((void*)(size_t)(x)) - - // Keys used by Java: --#define UNPACK_DEFLATE_HINT "unpack.deflate.hint" -+#define UNPACK_DEFLATE_HINT "unpack.deflate.hint" - --#define COM_PREFIX "com.sun.java.util.jar.pack." --#define UNPACK_MODIFICATION_TIME COM_PREFIX"unpack.modification.time" --#define DEBUG_VERBOSE COM_PREFIX"verbose" -+#define COM_PREFIX "com.sun.java.util.jar.pack." -+#define UNPACK_MODIFICATION_TIME COM_PREFIX"unpack.modification.time" -+#define DEBUG_VERBOSE COM_PREFIX"verbose" - --#define ZIP_ARCHIVE_MARKER_COMMENT "PACK200" -+#define ZIP_ARCHIVE_MARKER_COMMENT "PACK200" - - // The following are not known to the Java classes: --#define UNPACK_LOG_FILE COM_PREFIX"unpack.log.file" --#define UNPACK_REMOVE_PACKFILE COM_PREFIX"unpack.remove.packfile" -+#define UNPACK_LOG_FILE COM_PREFIX"unpack.log.file" -+#define UNPACK_REMOVE_PACKFILE COM_PREFIX"unpack.remove.packfile" - - - // Called from unpacker layers --#define _CHECK_DO(t,x) { if (t) {x;} } -+#define _CHECK_DO(t,x) { if (t) {x;} } - --#define CHECK _CHECK_DO(aborting(), return) --#define CHECK_(y) _CHECK_DO(aborting(), return y) --#define CHECK_0 _CHECK_DO(aborting(), return 0) -+#define CHECK _CHECK_DO(aborting(), return) -+#define CHECK_(y) _CHECK_DO(aborting(), return y) -+#define CHECK_0 _CHECK_DO(aborting(), return 0) - --#define CHECK_NULL(p) _CHECK_DO((p)==null, return) --#define CHECK_NULL_(y,p) _CHECK_DO((p)==null, return y) --#define CHECK_NULL_0(p) _CHECK_DO((p)==null, return 0) -+#define CHECK_NULL(p) _CHECK_DO((p)==null, return) -+#define CHECK_NULL_(y,p) _CHECK_DO((p)==null, return y) -+#define CHECK_NULL_0(p) _CHECK_DO((p)==null, return 0) - - #define CHECK_COUNT(t) if (t < 0){abort("bad value count");} CHECK - -diff --git a/src/share/native/com/sun/java/util/jar/pack/jni.cpp b/src/share/native/com/sun/java/util/jar/pack/jni.cpp ---- jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp -+++ jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -43,6 +43,9 @@ - #include "bands.h" - #include "constants.h" - #include "zip.h" -+ -+#include "jni_util.h" -+ - #include "unpack.h" - - -@@ -50,17 +53,19 @@ static jmethodID currentInstMID; - static jmethodID currentInstMID; - static jmethodID readInputMID; - static jclass NIclazz; -+static jmethodID getUnpackerPtrMID; - - static char* dbg = null; - - #define THROW_IOE(x) JNU_ThrowIOException(env,x) - - static jlong read_input_via_jni(unpacker* self, -- void* buf, jlong minlen, jlong maxlen); -- -+ void* buf, jlong minlen, jlong maxlen); -+ - static unpacker* get_unpacker(JNIEnv *env, jobject pObj, bool noCreate=false) { -- unpacker* uPtr = (unpacker*) env->GetLongField(pObj, unpackerPtrFID); -- //fprintf(stderr, "get_unpacker(%p) uPtr=%p\n", pObj, uPtr); -+ unpacker* uPtr; -+ jlong p = env->CallLongMethod(pObj, getUnpackerPtrMID); -+ uPtr = (unpacker*)jlong2ptr(p); - if (uPtr == null) { - if (noCreate) return null; - uPtr = new unpacker(); -@@ -89,11 +94,15 @@ static unpacker* get_unpacker() { - if (env == null) - return null; - jobject pObj = env->CallStaticObjectMethod(NIclazz, currentInstMID); -- //fprintf(stderr, "get_unpacker() pObj=%p\n", pObj); -- if (pObj == null) -- return null; -- // Got pObj and env; now do it the easy way. -- return get_unpacker(env, pObj); -+ //fprintf(stderr, "get_unpacker0() pObj=%p\n", pObj); -+ if (pObj != null) { -+ // Got pObj and env; now do it the easy way. -+ return get_unpacker(env, pObj); -+ } -+ // this should really not happen, if it does something is seriously -+ // wrong throw an exception -+ THROW_IOE(ERROR_INTERNAL); -+ return null; - } - - static void free_unpacker(JNIEnv *env, jobject pObj, unpacker* uPtr) { -@@ -113,36 +122,47 @@ unpacker* unpacker::current() { - - // Callback for fetching data, Java style. Calls NativeUnpack.readInputFn(). - static jlong read_input_via_jni(unpacker* self, -- void* buf, jlong minlen, jlong maxlen) { -+ void* buf, jlong minlen, jlong maxlen) { - JNIEnv* env = (JNIEnv*) self->jnienv; - jobject pbuf = env->NewDirectByteBuffer(buf, maxlen); - return env->CallLongMethod((jobject) self->jniobj, readInputMID, -- pbuf, minlen); -+ pbuf, minlen); - } - --JNIEXPORT void JNICALL -+JNIEXPORT void JNICALL - Java_com_sun_java_util_jar_pack_NativeUnpack_initIDs(JNIEnv *env, jclass clazz) { -+#ifndef PRODUCT - dbg = getenv("DEBUG_ATTACH"); - while( dbg != null) { sleep(10); } -+#endif - NIclazz = (jclass) env->NewGlobalRef(clazz); - unpackerPtrFID = env->GetFieldID(clazz, "unpackerPtr", "J"); - currentInstMID = env->GetStaticMethodID(clazz, "currentInstance", -- "()Ljava/lang/Object;"); -+ "()Ljava/lang/Object;"); - readInputMID = env->GetMethodID(clazz, "readInputFn", -- "(Ljava/nio/ByteBuffer;J)J"); -+ "(Ljava/nio/ByteBuffer;J)J"); -+ -+ getUnpackerPtrMID = env->GetMethodID(clazz, "getUnpackerPtr", "()J"); -+ - if (unpackerPtrFID == null || - currentInstMID == null || - readInputMID == null || -- NIclazz == null) { -+ NIclazz == null || -+ getUnpackerPtrMID == null) { - THROW_IOE("cannot init class members"); - } - } - --JNIEXPORT jlong JNICALL -+JNIEXPORT jlong JNICALL - Java_com_sun_java_util_jar_pack_NativeUnpack_start(JNIEnv *env, jobject pObj, -- jobject pBuf, jlong offset) { -- unpacker* uPtr = get_unpacker(env, pObj); -- -+ jobject pBuf, jlong offset) { -+ // try to get the unpacker pointer the hard way first, we do this to ensure -+ // valid object pointers and env is intact, if not now is good time to bail. -+ unpacker* uPtr = get_unpacker(); -+ //fprintf(stderr, "start(%p) uPtr=%p initializing\n", pObj, uPtr); -+ if (uPtr == null) { -+ return -1; -+ } - // redirect our io to the default log file or whatever. - uPtr->redirect_stdio(); - -@@ -158,6 +178,13 @@ Java_com_sun_java_util_jar_pack_NativeUn - else - { buf = (char*)buf + (size_t)offset; buflen -= (size_t)offset; } - } -+ -+ // before we start off we make sure there is no other error by the time we -+ // get here -+ if (uPtr->aborting()) { -+ THROW_IOE(uPtr->get_abort_message()); -+ return 0; -+ } - - uPtr->start(buf, buflen); - if (uPtr->aborting()) { -@@ -166,13 +193,13 @@ Java_com_sun_java_util_jar_pack_NativeUn - } - - return ((jlong) -- uPtr->get_segments_remaining() << 32) -+ uPtr->get_segments_remaining() << 32) - + uPtr->get_files_remaining(); - } - --JNIEXPORT jboolean JNICALL --Java_com_sun_java_util_jar_pack_NativeUnpack_getNextFile(JNIEnv *env, jobject pObj, -- jobjectArray pParts) { -+JNIEXPORT jboolean JNICALL -+Java_com_sun_java_util_jar_pack_NativeUnpack_getNextFile(JNIEnv *env, jobject pObj, -+ jobjectArray pParts) { - - unpacker* uPtr = get_unpacker(env, pObj); - unpacker::file* filep = uPtr->get_next_file(); -@@ -201,19 +228,19 @@ Java_com_sun_java_util_jar_pack_NativeUn - jobject pDataBuf = null; - if (filep->data[0].len > 0) - pDataBuf = env->NewDirectByteBuffer(filep->data[0].ptr, -- filep->data[0].len); -+ filep->data[0].len); - env->SetObjectArrayElement(pParts, pidx++, pDataBuf); - pDataBuf = null; - if (filep->data[1].len > 0) - pDataBuf = env->NewDirectByteBuffer(filep->data[1].ptr, -- filep->data[1].len); -+ filep->data[1].len); - env->SetObjectArrayElement(pParts, pidx++, pDataBuf); - - return true; - } - - --JNIEXPORT jobject JNICALL -+JNIEXPORT jobject JNICALL - Java_com_sun_java_util_jar_pack_NativeUnpack_getUnusedInput(JNIEnv *env, jobject pObj) { - unpacker* uPtr = get_unpacker(env, pObj); - unpacker::file* filep = &uPtr->cur_file; -@@ -225,14 +252,18 @@ Java_com_sun_java_util_jar_pack_NativeUn - - // We have fetched all the files. - // Now swallow up any remaining input. -- if (uPtr->input_remaining() == 0) -+ if (uPtr->input_remaining() == 0) { - return null; -- else -- return env->NewDirectByteBuffer(uPtr->input_scan(), -- uPtr->input_remaining()); -+ } -+ else { -+ bytes remaining_bytes; -+ remaining_bytes.malloc(uPtr->input_remaining()); -+ remaining_bytes.copyFrom(uPtr->input_scan(), uPtr->input_remaining()); -+ return env->NewDirectByteBuffer(remaining_bytes.ptr, remaining_bytes.len); -+ } - } - --JNIEXPORT jlong JNICALL -+JNIEXPORT jlong JNICALL - Java_com_sun_java_util_jar_pack_NativeUnpack_finish(JNIEnv *env, jobject pObj) { - unpacker* uPtr = get_unpacker(env, pObj, false); - if (uPtr == null) return 0; -@@ -241,9 +272,9 @@ Java_com_sun_java_util_jar_pack_NativeUn - return consumed; - } - --JNIEXPORT jboolean JNICALL --Java_com_sun_java_util_jar_pack_NativeUnpack_setOption(JNIEnv *env, jobject pObj, -- jstring pProp, jstring pValue) { -+JNIEXPORT jboolean JNICALL -+Java_com_sun_java_util_jar_pack_NativeUnpack_setOption(JNIEnv *env, jobject pObj, -+ jstring pProp, jstring pValue) { - unpacker* uPtr = get_unpacker(env, pObj); - const char* prop = env->GetStringUTFChars(pProp, JNI_FALSE); - const char* value = env->GetStringUTFChars(pValue, JNI_FALSE); -@@ -253,9 +284,9 @@ Java_com_sun_java_util_jar_pack_NativeUn - return retval; - } - --JNIEXPORT jstring JNICALL --Java_com_sun_java_util_jar_pack_NativeUnpack_getOption(JNIEnv *env, jobject pObj, -- jstring pProp) { -+JNIEXPORT jstring JNICALL -+Java_com_sun_java_util_jar_pack_NativeUnpack_getOption(JNIEnv *env, jobject pObj, -+ jstring pProp) { - - unpacker* uPtr = get_unpacker(env, pObj); - const char* prop = env->GetStringUTFChars(pProp, JNI_FALSE); -diff --git a/src/share/native/com/sun/java/util/jar/pack/unpack.cpp b/src/share/native/com/sun/java/util/jar/pack/unpack.cpp ---- jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp -+++ jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -38,7 +38,7 @@ - #include <time.h> - - -- -+ - - #include "defines.h" - #include "bytes.h" -@@ -185,9 +185,9 @@ struct entry { - || (tag2 == CONSTANT_Utf8 && tag == CONSTANT_Signature) - #ifndef PRODUCT - || (tag2 == CONSTANT_Literal -- && tag >= CONSTANT_Integer && tag <= CONSTANT_String && tag != CONSTANT_Class) -+ && tag >= CONSTANT_Integer && tag <= CONSTANT_String && tag != CONSTANT_Class) - || (tag2 == CONSTANT_Member -- && tag >= CONSTANT_Fieldref && tag <= CONSTANT_InterfaceMethodref) -+ && tag >= CONSTANT_Fieldref && tag <= CONSTANT_InterfaceMethodref) - #endif - ; - } -@@ -238,9 +238,9 @@ int entry::typeSize() { - // else fall through - case 'L': - sigp = strchr(sigp, ';'); -- if (sigp == null) { -- unpack_abort("bad data"); -- return 0; -+ if (sigp == null) { -+ unpack_abort("bad data"); -+ return 0; - } - sigp += 1; - break; -@@ -252,11 +252,13 @@ int entry::typeSize() { - } - - inline cpindex* cpool::getFieldIndex(entry* classRef) { -+ if (classRef == NULL) { abort("missing class reference"); return NULL; } - assert(classRef->tagMatches(CONSTANT_Class)); - assert((uint)classRef->inord < tag_count[CONSTANT_Class]); - return &member_indexes[classRef->inord*2+0]; - } - inline cpindex* cpool::getMethodIndex(entry* classRef) { -+ if (classRef == NULL) { abort("missing class reference"); return NULL; } - assert(classRef->tagMatches(CONSTANT_Class)); - assert((uint)classRef->inord < tag_count[CONSTANT_Class]); - return &member_indexes[classRef->inord*2+1]; -@@ -512,11 +514,10 @@ void unpacker::read_file_header() { - AH_CP_NUMBER_LEN = 4, // int/float/long/double - AH_SPECIAL_FORMAT_LEN = 2, // layouts/band-headers - AH_LENGTH_MIN = AH_LENGTH -- -(AH_FILE_HEADER_LEN+AH_SPECIAL_FORMAT_LEN+AH_CP_NUMBER_LEN), -- ARCHIVE_SIZE_MIN = AH_LENGTH_MIN - (AH_LENGTH_0 + AH_ARCHIVE_SIZE_LEN), -+ -(AH_FILE_HEADER_LEN+AH_SPECIAL_FORMAT_LEN+AH_CP_NUMBER_LEN), -+ ARCHIVE_SIZE_MIN = AH_LENGTH_MIN - (AH_LENGTH_0 + AH_ARCHIVE_SIZE_LEN), - FIRST_READ = MAGIC_BYTES + AH_LENGTH_MIN - }; -- - - assert(AH_LENGTH_MIN == 15); // # of UNSIGNED5 fields required after archive_magic - assert(ARCHIVE_SIZE_MIN == 10); // # of UNSIGNED5 fields required after archive_size -@@ -580,15 +581,15 @@ void unpacker::read_file_header() { - for (;;) { - jarout->write_data(rp, input_remaining()); - if (foreign_buf) -- break; // one-time use of a passed in buffer -+ break; // one-time use of a passed in buffer - if (input.size() < CHUNK) { -- // Get some breathing room. -- input.set(U_NEW(byte, (size_t) CHUNK + C_SLOP), (size_t) CHUNK); -- CHECK; -+ // Get some breathing room. -+ input.set(U_NEW(byte, (size_t) CHUNK + C_SLOP), (size_t) CHUNK); -+ CHECK; - } - rp = rplimit = input.base(); - if (!ensure_input(1)) -- break; -+ break; - } - jarout->closeJarFile(false); - #endif -@@ -612,16 +613,16 @@ void unpacker::read_file_header() { - hdrVals += 2; - - if (magic != JAVA_PACKAGE_MAGIC || -- (majver != JAVA5_PACKAGE_MAJOR_VERSION && -- majver != JAVA6_PACKAGE_MAJOR_VERSION) || -- (minver != JAVA5_PACKAGE_MINOR_VERSION && -+ (majver != JAVA5_PACKAGE_MAJOR_VERSION && -+ majver != JAVA6_PACKAGE_MAJOR_VERSION) || -+ (minver != JAVA5_PACKAGE_MINOR_VERSION && - minver != JAVA6_PACKAGE_MINOR_VERSION)) { - char message[200]; - sprintf(message, "@" ERROR_FORMAT ": magic/ver = " -- "%08X/%d.%d should be %08X/%d.%d OR %08X/%d.%d\n", -- magic, majver, minver, -- JAVA_PACKAGE_MAGIC, JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION, -- JAVA_PACKAGE_MAGIC, JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION); -+ "%08X/%d.%d should be %08X/%d.%d OR %08X/%d.%d\n", -+ magic, majver, minver, -+ JAVA_PACKAGE_MAGIC, JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION, -+ JAVA_PACKAGE_MAGIC, JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION); - abort(message); - } - CHECK; -@@ -635,7 +636,7 @@ void unpacker::read_file_header() { - #undef ORBIT - if ((archive_options & ~OPTION_LIMIT) != 0) { - fprintf(errstrm, "Warning: Illegal archive options 0x%x\n", -- archive_options); -+ archive_options); - abort("illegal archive options"); - return; - } -@@ -675,7 +676,7 @@ void unpacker::read_file_header() { - if (archive_size < header_size_1) { - abort("too much read-ahead"); // somehow we pre-fetched too much? - return; -- } -+ } - input.set(U_NEW(byte, add_size(header_size_0, archive_size, C_SLOP)), - (size_t) header_size_0 + archive_size); - CHECK; -@@ -756,9 +757,9 @@ void unpacker::read_file_header() { - case CONSTANT_Float: - case CONSTANT_Long: - case CONSTANT_Double: -- cp_counts[k] = 0; -- hdrValsSkipped += 1; -- continue; -+ cp_counts[k] = 0; -+ hdrValsSkipped += 1; -+ continue; - } - } - cp_counts[k] = hdr.getInt(); -@@ -813,7 +814,7 @@ void unpacker::read_file_header() { - bytes band_headers; - // The "1+" allows an initial byte to be pushed on the front. - band_headers.set(1+U_NEW(byte, 1+band_headers_size+C_SLOP), -- band_headers_size); -+ band_headers_size); - CHECK; - // Start scanning band headers here: - band_headers.copyFrom(rp, band_headers.len); -@@ -874,7 +875,7 @@ void cpool::init(unpacker* u_, int count - IMPLICIT_ENTRY_COUNT = 1 // empty Utf8 string - }; - if (len >= (1<<29) || len < 0 -- || next_entry >= CP_SIZE_LIMIT+IMPLICIT_ENTRY_COUNT) { -+ || next_entry >= CP_SIZE_LIMIT+IMPLICIT_ENTRY_COUNT) { - abort("archive too large: constant pool limit exceeded"); - return; - } -@@ -935,9 +936,9 @@ static byte* skip_Utf8_chars(byte* cp, i - int ch = *cp & 0xFF; - if ((ch & 0xC0) != 0x80) { - if (len-- == 0) -- return cp; -+ return cp; - if (ch < 0x80 && len == 0) -- return cp+1; -+ return cp+1; - } - } - } -@@ -963,9 +964,9 @@ static int compare_Utf8_chars(bytes& b1, - if (c1 == 0xC0 && (p1[i+1] & 0xFF) == 0x80) c1 = 0; - if (c2 == 0xC0 && (p2[i+1] & 0xFF) == 0x80) c2 = 0; - if (c0 == 0xC0) { -- assert(((c1|c2) & 0xC0) == 0x80); // c1 & c2 are extension chars -- if (c1 == 0x80) c1 = 0; // will sort below c2 -- if (c2 == 0x80) c2 = 0; // will sort below c1 -+ assert(((c1|c2) & 0xC0) == 0x80); // c1 & c2 are extension chars -+ if (c1 == 0x80) c1 = 0; // will sort below c2 -+ if (c2 == 0x80) c2 = 0; // will sort below c1 - } - return c1 - c2; - } -@@ -1024,9 +1025,9 @@ void unpacker::read_Utf8_values(entry* c - chars.malloc(size3); - } else { - if (!charbuf.canAppend(size3+1)) { -- assert(charbuf.allocated == 0 || tmallocs.contains(charbuf.base())); -- charbuf.init(CHUNK); // Reset to new buffer. -- tmallocs.add(charbuf.base()); -+ assert(charbuf.allocated == 0 || tmallocs.contains(charbuf.base())); -+ charbuf.init(CHUNK); // Reset to new buffer. -+ tmallocs.add(charbuf.base()); - } - chars.set(charbuf.grow(size3+1), size3); - } -@@ -1191,9 +1192,9 @@ void unpacker::read_single_refs(band& cp - // Maintain cross-reference: - entry* &htref = cp.hashTabRef(indexTag, e.value.b); - if (htref == null) { -- // Note that if two identical classes are transmitted, -- // the first is taken to be the canonical one. -- htref = &e; -+ // Note that if two identical classes are transmitted, -+ // the first is taken to be the canonical one. -+ htref = &e; - } - } - } -@@ -1202,7 +1203,7 @@ void unpacker::read_single_refs(band& cp - - maybe_inline - void unpacker::read_double_refs(band& cp_band, byte ref1Tag, byte ref2Tag, -- entry* cpMap, int len) { -+ entry* cpMap, int len) { - band& cp_band1 = cp_band; - band& cp_band2 = cp_band.nextBand(); - cp_band1.setIndexByTag(ref1Tag); -@@ -1214,6 +1215,7 @@ void unpacker::read_double_refs(band& cp - entry& e = cpMap[i]; - e.refs = U_NEW(entry*, e.nrefs = 2); - e.refs[0] = cp_band1.getRef(); -+ CHECK; - e.refs[1] = cp_band2.getRef(); - CHECK; - } -@@ -1302,23 +1304,23 @@ void unpacker::read_cp() { - break; - case CONSTANT_NameandType: - read_double_refs(cp_Descr_name /*& cp_Descr_type*/, -- CONSTANT_Utf8, CONSTANT_Signature, -- cpMap, len); -+ CONSTANT_Utf8, CONSTANT_Signature, -+ cpMap, len); - break; - case CONSTANT_Fieldref: - read_double_refs(cp_Field_class /*& cp_Field_desc*/, -- CONSTANT_Class, CONSTANT_NameandType, -- cpMap, len); -+ CONSTANT_Class, CONSTANT_NameandType, -+ cpMap, len); - break; - case CONSTANT_Methodref: - read_double_refs(cp_Method_class /*& cp_Method_desc*/, -- CONSTANT_Class, CONSTANT_NameandType, -- cpMap, len); -+ CONSTANT_Class, CONSTANT_NameandType, -+ cpMap, len); - break; - case CONSTANT_InterfaceMethodref: - read_double_refs(cp_Imethod_class /*& cp_Imethod_desc*/, -- CONSTANT_Class, CONSTANT_NameandType, -- cpMap, len); -+ CONSTANT_Class, CONSTANT_NameandType, -+ cpMap, len); - break; - default: - assert(false); -@@ -1384,8 +1386,8 @@ inline - inline - unpacker::layout_definition* - unpacker::attr_definitions::defineLayout(int idx, -- entry* nameEntry, -- const char* layout) { -+ entry* nameEntry, -+ const char* layout) { - const char* name = nameEntry->value.b.strval(); - layout_definition* lo = defineLayout(idx, name, layout); - CHECK_0; -@@ -1395,8 +1397,8 @@ unpacker::attr_definitions::defineLayout - - unpacker::layout_definition* - unpacker::attr_definitions::defineLayout(int idx, -- const char* name, -- const char* layout) { -+ const char* name, -+ const char* layout) { - assert(flag_limit != 0); // must be set up already - if (idx >= 0) { - // Fixed attr. -@@ -1419,12 +1421,12 @@ unpacker::attr_definitions::defineLayout - } - CHECK_0; - layouts.get(idx) = lo; -- return lo; -+ return lo; - } - - band** - unpacker::attr_definitions::buildBands(unpacker::layout_definition* lo) { -- int i; -+ int i; - if (lo->elems != null) - return lo->bands(); - if (lo->layout[0] == '\0') { -@@ -1448,11 +1450,11 @@ unpacker::attr_definitions::buildBands(u - int num_callables = 0; - if (hasCallables) { - while (bands[num_callables] != null) { -- if (bands[num_callables]->le_kind != EK_CBLE) { -- abort("garbage mixed with callables"); -- break; -- } -- num_callables += 1; -+ if (bands[num_callables]->le_kind != EK_CBLE) { -+ abort("garbage mixed with callables"); -+ break; -+ } -+ num_callables += 1; - } - } - for (i = 0; i < calls_to_link.length(); i++) { -@@ -1461,8 +1463,8 @@ unpacker::attr_definitions::buildBands(u - // Determine the callee. - int call_num = call.le_len; - if (call_num < 0 || call_num >= num_callables) { -- abort("bad call in layout"); -- break; -+ abort("bad call in layout"); -+ break; - } - band& cble = *bands[call_num]; - // Link the call to it. -@@ -1540,7 +1542,7 @@ unpacker::attr_definitions::buildBands(u - - const char* - unpacker::attr_definitions::parseIntLayout(const char* lp, band* &res, -- byte le_kind, bool can_be_signed) { -+ byte le_kind, bool can_be_signed) { - const char* lp0 = lp; - band* b = U_NEW(band, 1); - CHECK_(lp); -@@ -1619,7 +1621,7 @@ unpacker::attr_definitions::popBody(int - - const char* - unpacker::attr_definitions::parseLayout(const char* lp, band** &res, -- int curCble) { -+ int curCble) { - const char* lp0 = lp; - int bs_base = band_stack.length(); - bool top_level = (bs_base == 0); -@@ -1636,18 +1638,18 @@ unpacker::attr_definitions::parseLayout( - break; - case 'P': - { -- int le_bci = EK_BCI; -- if (*lp == 'O') { -- ++lp; -- le_bci = EK_BCID; -- } -- assert(*lp != 'S'); // no PSH, etc. -- lp = parseIntLayout(lp, b, EK_INT); -- b->le_bci = le_bci; -- if (le_bci == EK_BCI) -- b->defc = coding::findBySpec(BCI5_spec); -- else -- b->defc = coding::findBySpec(BRANCH5_spec); -+ int le_bci = EK_BCI; -+ if (*lp == 'O') { -+ ++lp; -+ le_bci = EK_BCID; -+ } -+ assert(*lp != 'S'); // no PSH, etc. -+ lp = parseIntLayout(lp, b, EK_INT); -+ b->le_bci = le_bci; -+ if (le_bci == EK_BCI) -+ b->defc = coding::findBySpec(BCI5_spec); -+ else -+ b->defc = coding::findBySpec(BRANCH5_spec); - } - break; - case 'O': -@@ -1665,25 +1667,25 @@ unpacker::attr_definitions::parseLayout( - case 'T': // union: 'T' any_int union_case* '(' ')' '[' body ']' - lp = parseIntLayout(lp, b, EK_UN, can_be_signed); - { -- int union_base = band_stack.length(); -- for (;;) { // for each case -- band& k_case = *U_NEW(band, 1); -- CHECK_(lp); -- band_stack.add(&k_case); -- k_case.le_kind = EK_CASE; -- k_case.bn = bands_made++; -- if (*lp++ != '(') { -- abort("bad union case"); -- return ""; -- } -- if (*lp++ != ')') { -- --lp; // reparse -- // Read some case values. (Use band_stack for temp. storage.) -- int case_base = band_stack.length(); -- for (;;) { -- int caseval = 0; -- lp = parseNumeral(lp, caseval); -- band_stack.add((void*)caseval); -+ int union_base = band_stack.length(); -+ for (;;) { // for each case -+ band& k_case = *U_NEW(band, 1); -+ CHECK_(lp); -+ band_stack.add(&k_case); -+ k_case.le_kind = EK_CASE; -+ k_case.bn = bands_made++; -+ if (*lp++ != '(') { -+ abort("bad union case"); -+ return ""; -+ } -+ if (*lp++ != ')') { -+ --lp; // reparse -+ // Read some case values. (Use band_stack for temp. storage.) -+ int case_base = band_stack.length(); -+ for (;;) { -+ int caseval = 0; -+ lp = parseNumeral(lp, caseval); -+ band_stack.add((void*)caseval); - if (*lp == '-') { - // new in version 160, allow (1-5) for (1,2,3,4,5) - if (u->majver < JAVA6_PACKAGE_MAJOR_VERSION) { -@@ -1706,111 +1708,111 @@ unpacker::attr_definitions::parseLayout( - if (caseval == caselimit) break; - } - } -- if (*lp != ',') break; -- lp++; -- } -- if (*lp++ != ')') { -- abort("bad case label"); -- return ""; -- } -- // save away the case labels -- int ntags = band_stack.length() - case_base; -- int* tags = U_NEW(int, add_size(ntags, 1)); -- CHECK_(lp); -- k_case.le_casetags = tags; -- *tags++ = ntags; -- for (int i = 0; i < ntags; i++) { -- *tags++ = ptrlowbits(band_stack.get(case_base+i)); -- } -- band_stack.popTo(case_base); -- CHECK_(lp); -- } -- // Got le_casetags. Now grab the body. -- assert(*lp == '['); -- ++lp; -- lp = parseLayout(lp, k_case.le_body, curCble); -- CHECK_(lp); -- if (k_case.le_casetags == null) break; // done -- } -- b->le_body = popBody(union_base); -+ if (*lp != ',') break; -+ lp++; -+ } -+ if (*lp++ != ')') { -+ abort("bad case label"); -+ return ""; -+ } -+ // save away the case labels -+ int ntags = band_stack.length() - case_base; -+ int* tags = U_NEW(int, add_size(ntags, 1)); -+ CHECK_(lp); -+ k_case.le_casetags = tags; -+ *tags++ = ntags; -+ for (int i = 0; i < ntags; i++) { -+ *tags++ = ptrlowbits(band_stack.get(case_base+i)); -+ } -+ band_stack.popTo(case_base); -+ CHECK_(lp); -+ } -+ // Got le_casetags. Now grab the body. -+ assert(*lp == '['); -+ ++lp; -+ lp = parseLayout(lp, k_case.le_body, curCble); -+ CHECK_(lp); -+ if (k_case.le_casetags == null) break; // done -+ } -+ b->le_body = popBody(union_base); - } - break; - case '(': // call: '(' -?NN* ')' - { -- band& call = *U_NEW(band, 1); -- CHECK_(lp); -- band_stack.add(&call); -- call.le_kind = EK_CALL; -- call.bn = bands_made++; -- call.le_body = U_NEW(band*, 2); // fill in later -- int call_num = 0; -- lp = parseNumeral(lp, call_num); -- call.le_back = (call_num <= 0); -- call_num += curCble; // numeral is self-relative offset -- call.le_len = call_num; //use le_len as scratch -- calls_to_link.add(&call); -- CHECK_(lp); -- if (*lp++ != ')') { -- abort("bad call label"); -- return ""; -+ band& call = *U_NEW(band, 1); -+ CHECK_(lp); -+ band_stack.add(&call); -+ call.le_kind = EK_CALL; -+ call.bn = bands_made++; -+ call.le_body = U_NEW(band*, 2); // fill in later -+ int call_num = 0; -+ lp = parseNumeral(lp, call_num); -+ call.le_back = (call_num <= 0); -+ call_num += curCble; // numeral is self-relative offset -+ call.le_len = call_num; //use le_len as scratch -+ calls_to_link.add(&call); -+ CHECK_(lp); -+ if (*lp++ != ')') { -+ abort("bad call label"); -+ return ""; - } - } - break; - case 'K': // reference_type: constant_ref - case 'R': // reference_type: schema_ref - { -- int ixTag = CONSTANT_None; -- if (lp[-1] == 'K') { -- switch (*lp++) { -- case 'I': ixTag = CONSTANT_Integer; break; -- case 'J': ixTag = CONSTANT_Long; break; -- case 'F': ixTag = CONSTANT_Float; break; -- case 'D': ixTag = CONSTANT_Double; break; -- case 'S': ixTag = CONSTANT_String; break; -- case 'Q': ixTag = CONSTANT_Literal; break; -- } -- } else { -- switch (*lp++) { -- case 'C': ixTag = CONSTANT_Class; break; -- case 'S': ixTag = CONSTANT_Signature; break; -- case 'D': ixTag = CONSTANT_NameandType; break; -- case 'F': ixTag = CONSTANT_Fieldref; break; -- case 'M': ixTag = CONSTANT_Methodref; break; -- case 'I': ixTag = CONSTANT_InterfaceMethodref; break; -- case 'U': ixTag = CONSTANT_Utf8; break; //utf8_ref -- case 'Q': ixTag = CONSTANT_All; break; //untyped_ref -- } -- } -- if (ixTag == CONSTANT_None) { -- abort("bad reference layout"); -- break; -- } -- bool nullOK = false; -- if (*lp == 'N') { -- nullOK = true; -- lp++; -- } -- lp = parseIntLayout(lp, b, EK_REF); -- b->defc = coding::findBySpec(UNSIGNED5_spec); -- b->initRef(ixTag, nullOK); -+ int ixTag = CONSTANT_None; -+ if (lp[-1] == 'K') { -+ switch (*lp++) { -+ case 'I': ixTag = CONSTANT_Integer; break; -+ case 'J': ixTag = CONSTANT_Long; break; -+ case 'F': ixTag = CONSTANT_Float; break; -+ case 'D': ixTag = CONSTANT_Double; break; -+ case 'S': ixTag = CONSTANT_String; break; -+ case 'Q': ixTag = CONSTANT_Literal; break; -+ } -+ } else { -+ switch (*lp++) { -+ case 'C': ixTag = CONSTANT_Class; break; -+ case 'S': ixTag = CONSTANT_Signature; break; -+ case 'D': ixTag = CONSTANT_NameandType; break; -+ case 'F': ixTag = CONSTANT_Fieldref; break; -+ case 'M': ixTag = CONSTANT_Methodref; break; -+ case 'I': ixTag = CONSTANT_InterfaceMethodref; break; -+ case 'U': ixTag = CONSTANT_Utf8; break; //utf8_ref -+ case 'Q': ixTag = CONSTANT_All; break; //untyped_ref -+ } -+ } -+ if (ixTag == CONSTANT_None) { -+ abort("bad reference layout"); -+ break; -+ } -+ bool nullOK = false; -+ if (*lp == 'N') { -+ nullOK = true; -+ lp++; -+ } -+ lp = parseIntLayout(lp, b, EK_REF); -+ b->defc = coding::findBySpec(UNSIGNED5_spec); -+ b->initRef(ixTag, nullOK); - } - break; - case '[': - { -- // [callable1][callable2]... -- if (!top_level) { -- abort("bad nested callable"); -- break; -- } -- curCble += 1; -- NOT_PRODUCT(int call_num = band_stack.length() - bs_base); -- band& cble = *U_NEW(band, 1); -- CHECK_(lp); -- band_stack.add(&cble); -- cble.le_kind = EK_CBLE; -- NOT_PRODUCT(cble.le_len = call_num); -- cble.bn = bands_made++; -- lp = parseLayout(lp, cble.le_body, curCble); -+ // [callable1][callable2]... -+ if (!top_level) { -+ abort("bad nested callable"); -+ break; -+ } -+ curCble += 1; -+ NOT_PRODUCT(int call_num = band_stack.length() - bs_base); -+ band& cble = *U_NEW(band, 1); -+ CHECK_(lp); -+ band_stack.add(&cble); -+ cble.le_kind = EK_CBLE; -+ NOT_PRODUCT(cble.le_len = call_num); -+ cble.bn = bands_made++; -+ lp = parseLayout(lp, cble.le_body, curCble); - } - break; - case ']': -@@ -1880,10 +1882,10 @@ void unpacker::read_attr_defs() { - "(115)[RUH]" - "(91)[NH[(0)]]" - "(64)[" -- // nested annotation: -- "RSH" -- "NH[RUH(0)]" -- "]" -+ // nested annotation: -+ "RSH" -+ "NH[RUH(0)]" -+ "]" - "()[]" - "]" - ); -@@ -1897,16 +1899,16 @@ void unpacker::read_attr_defs() { - for (i = 0; i < ATTR_CONTEXT_LIMIT; i++) { - attr_definitions& ad = attr_defs[i]; - ad.defineLayout(X_ATTR_RuntimeVisibleAnnotations, -- "RuntimeVisibleAnnotations", md_layout_A); -+ "RuntimeVisibleAnnotations", md_layout_A); - ad.defineLayout(X_ATTR_RuntimeInvisibleAnnotations, -- "RuntimeInvisibleAnnotations", md_layout_A); -+ "RuntimeInvisibleAnnotations", md_layout_A); - if (i != ATTR_CONTEXT_METHOD) continue; - ad.defineLayout(METHOD_ATTR_RuntimeVisibleParameterAnnotations, -- "RuntimeVisibleParameterAnnotations", md_layout_P); -+ "RuntimeVisibleParameterAnnotations", md_layout_P); - ad.defineLayout(METHOD_ATTR_RuntimeInvisibleParameterAnnotations, -- "RuntimeInvisibleParameterAnnotations", md_layout_P); -+ "RuntimeInvisibleParameterAnnotations", md_layout_P); - ad.defineLayout(METHOD_ATTR_AnnotationDefault, -- "AnnotationDefault", md_layout_V); -+ "AnnotationDefault", md_layout_V); - } - - attr_definition_headers.readData(attr_definition_count); -@@ -1939,6 +1941,7 @@ void unpacker::read_attr_defs() { - int attrc = ADH_BYTE_CONTEXT(header); - int idx = ADH_BYTE_INDEX(header); - entry* name = attr_definition_name.getRef(); -+ CHECK; - entry* layout = attr_definition_layout.getRef(); - CHECK; - attr_defs[attrc].defineLayout(idx, name, layout->value.b.strval()); -@@ -2043,7 +2046,9 @@ void unpacker::read_ics() { - if (ics[i].name == NO_ENTRY_YET) { - // Long form. - ics[i].outer = ic_outer_class.getRefN(); -+ CHECK; - ics[i].name = ic_name.getRefN(); -+ CHECK; - } else { - // Fill in outer and name based on inner. - bytes& n = ics[i].inner->value.b; -@@ -2058,48 +2063,48 @@ void unpacker::read_ics() { - int pkglen = lastIndexOf(SLASH_MIN, SLASH_MAX, n, nlen) + 1; - dollar2 = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, nlen); - if (dollar2 < 0) { -- abort(); -- return; -+ abort(); -+ return; - } - assert(dollar2 >= pkglen); - if (isDigitString(n, dollar2+1, nlen)) { -- // n = (<pkg>/)*<outer>$<number> -- number = n.slice(dollar2+1, nlen); -- name.set(null,0); -- dollar1 = dollar2; -+ // n = (<pkg>/)*<outer>$<number> -+ number = n.slice(dollar2+1, nlen); -+ name.set(null,0); -+ dollar1 = dollar2; - } else if (pkglen < (dollar1 -- = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, dollar2-1)) -- && isDigitString(n, dollar1+1, dollar2)) { -- // n = (<pkg>/)*<outer>$<number>$<name> -- number = n.slice(dollar1+1, dollar2); -- name = n.slice(dollar2+1, nlen); -+ = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, dollar2-1)) -+ && isDigitString(n, dollar1+1, dollar2)) { -+ // n = (<pkg>/)*<outer>$<number>$<name> -+ number = n.slice(dollar1+1, dollar2); -+ name = n.slice(dollar2+1, nlen); - } else { -- // n = (<pkg>/)*<outer>$<name> -- dollar1 = dollar2; -- number.set(null,0); -- name = n.slice(dollar2+1, nlen); -+ // n = (<pkg>/)*<outer>$<name> -+ dollar1 = dollar2; -+ number.set(null,0); -+ name = n.slice(dollar2+1, nlen); - } - if (number.ptr == null) -- pkgOuter = n.slice(0, dollar1); -+ pkgOuter = n.slice(0, dollar1); - else -- pkgOuter.set(null,0); -+ pkgOuter.set(null,0); - printcr(5,"=> %s$ 0%s $%s", -- pkgOuter.string(), number.string(), name.string()); -+ pkgOuter.string(), number.string(), name.string()); - - if (pkgOuter.ptr != null) -- ics[i].outer = cp.ensureClass(pkgOuter); -+ ics[i].outer = cp.ensureClass(pkgOuter); - - if (name.ptr != null) -- ics[i].name = cp.ensureUtf8(name); -+ ics[i].name = cp.ensureUtf8(name); - } - - // update child/sibling list - if (ics[i].outer != null) { - uint outord = ics[i].outer->inord; - if (outord != NO_INORD) { -- assert(outord < cp.tag_count[CONSTANT_Class]); -- ics[i].next_sibling = ic_child_index[outord]; -- ic_child_index[outord] = &ics[i]; -+ assert(outord < cp.tag_count[CONSTANT_Class]); -+ ics[i].next_sibling = ic_child_index[outord]; -+ ic_child_index[outord] = &ics[i]; - } - } - } -@@ -2149,7 +2154,7 @@ void unpacker::read_classes() { - read_code_headers(); - - printcr(1,"scanned %d classes, %d fields, %d methods, %d code headers", -- class_count, field_count, method_count, code_count); -+ class_count, field_count, method_count, code_count); - } - - maybe_inline -@@ -2226,11 +2231,11 @@ void unpacker::read_attrs(int attrc, int - band** bands = ad.buildBands(lo); - CHECK; - if (lo->hasCallables()) { -- for (i = 0; bands[i] != null; i++) { -- if (bands[i]->le_back) { -- assert(bands[i]->le_kind == EK_CBLE); -- backwardCounts += 1; -- } -+ for (i = 0; bands[i] != null; i++) { -+ if (bands[i]->le_back) { -+ assert(bands[i]->le_kind == EK_CBLE); -+ backwardCounts += 1; -+ } - } - } - } -@@ -2427,7 +2432,7 @@ void unpacker::attr_definitions::readBan - layout_definition* lo = getLayout(idx); - if (lo != null) { - printcr(1, "counted %d [redefined = %d predefined = %d] attributes of type %s.%s", -- count, isRedefined(idx), isPredefined(idx), -+ count, isRedefined(idx), isPredefined(idx), - ATTR_CONTEXT_NAME[attrc], lo->name); - } - bool hasCallables = lo->hasCallables(); -@@ -2444,10 +2449,10 @@ void unpacker::attr_definitions::readBan - band& j_cble = *bands[j]; - assert(j_cble.le_kind == EK_CBLE); - if (j_cble.le_back) { -- // Add in the predicted effects of backward calls, too. -- int back_calls = xxx_attr_calls().getInt(); -- j_cble.expectMoreLength(back_calls); -- // In a moment, more forward calls may increment j_cble.length. -+ // Add in the predicted effects of backward calls, too. -+ int back_calls = xxx_attr_calls().getInt(); -+ j_cble.expectMoreLength(back_calls); -+ // In a moment, more forward calls may increment j_cble.length. - } - } - // Now consult whichever callables have non-zero entry counts. -@@ -2467,38 +2472,38 @@ void unpacker::attr_definitions::readBan - switch (b.le_kind) { - case EK_REPL: - { -- int reps = b.getIntTotal(); -- readBandData(b.le_body, reps); -+ int reps = b.getIntTotal(); -+ readBandData(b.le_body, reps); - } - break; - case EK_UN: - { -- int remaining = count; -- for (k = 0; b.le_body[k] != null; k++) { -- band& k_case = *b.le_body[k]; -- int k_count = 0; -- if (k_case.le_casetags == null) { -- k_count = remaining; // last (empty) case -- } else { -- int* tags = k_case.le_casetags; -- int ntags = *tags++; // 1st element is length (why not?) -- while (ntags-- > 0) { -- int tag = *tags++; -- k_count += b.getIntCount(tag); -- } -- } -- readBandData(k_case.le_body, k_count); -- remaining -= k_count; -- } -- assert(remaining == 0); -+ int remaining = count; -+ for (k = 0; b.le_body[k] != null; k++) { -+ band& k_case = *b.le_body[k]; -+ int k_count = 0; -+ if (k_case.le_casetags == null) { -+ k_count = remaining; // last (empty) case -+ } else { -+ int* tags = k_case.le_casetags; -+ int ntags = *tags++; // 1st element is length (why not?) -+ while (ntags-- > 0) { -+ int tag = *tags++; -+ k_count += b.getIntCount(tag); -+ } -+ } -+ readBandData(k_case.le_body, k_count); -+ remaining -= k_count; -+ } -+ assert(remaining == 0); - } - break; - case EK_CALL: - // Push the count forward, if it is not a backward call. - if (!b.le_back) { -- band& cble = *b.le_body[0]; -- assert(cble.le_kind == EK_CBLE); -- cble.expectMoreLength(count); -+ band& cble = *b.le_body[0]; -+ assert(cble.le_kind == EK_CBLE); -+ cble.expectMoreLength(count); - } - break; - case EK_CBLE: -@@ -2522,12 +2527,12 @@ band** findMatchingCase(int matchTag, ba - int* tags = k_case.le_casetags; - int ntags = *tags++; // 1st element is length - for (; ntags > 0; ntags--) { -- int tag = *tags++; -- if (tag == matchTag) -- break; -+ int tag = *tags++; -+ if (tag == matchTag) -+ break; - } - if (ntags == 0) -- continue; // does not match -+ continue; // does not match - } - return k_case.le_body; - } -@@ -2549,46 +2554,47 @@ void unpacker::putlayout(band** body) { - if (b.defc != null) { - // It has data, so unparse an element. - if (b.ixTag != CONSTANT_None) { -- assert(le_kind == EK_REF); -- if (b.ixTag == CONSTANT_Literal) -- e = b.getRefUsing(cp.getKQIndex()); -- else -- e = b.getRefN(); -- switch (b.le_len) { -- case 0: break; -- case 1: putu1ref(e); break; -- case 2: putref(e); break; -- case 4: putu2(0); putref(e); break; -- default: assert(false); -- } -+ assert(le_kind == EK_REF); -+ if (b.ixTag == CONSTANT_Literal) -+ e = b.getRefUsing(cp.getKQIndex()); -+ else -+ e = b.getRefN(); -+ CHECK; -+ switch (b.le_len) { -+ case 0: break; -+ case 1: putu1ref(e); break; -+ case 2: putref(e); break; -+ case 4: putu2(0); putref(e); break; -+ default: assert(false); -+ } - } else { -- assert(le_kind == EK_INT || le_kind == EK_REPL || le_kind == EK_UN); -- x = b.getInt(); -- -- assert(!b.le_bci || prevBCI == to_bci(prevBII)); -- switch (b.le_bci) { -- case EK_BCI: // PH: transmit R(bci), store bci -- x = to_bci(prevBII = x); -- prevBCI = x; -- break; -- case EK_BCID: // POH: transmit D(R(bci)), store bci -- x = to_bci(prevBII += x); -- prevBCI = x; -- break; -- case EK_BCO: // OH: transmit D(R(bci)), store D(bci) -- x = to_bci(prevBII += x) - prevBCI; -- prevBCI += x; -- break; -- } -- assert(!b.le_bci || prevBCI == to_bci(prevBII)); -- -- switch (b.le_len) { -- case 0: break; -- case 1: putu1(x); break; -- case 2: putu2(x); break; -- case 4: putu4(x); break; -- default: assert(false); -- } -+ assert(le_kind == EK_INT || le_kind == EK_REPL || le_kind == EK_UN); -+ x = b.getInt(); -+ -+ assert(!b.le_bci || prevBCI == to_bci(prevBII)); -+ switch (b.le_bci) { -+ case EK_BCI: // PH: transmit R(bci), store bci -+ x = to_bci(prevBII = x); -+ prevBCI = x; -+ break; -+ case EK_BCID: // POH: transmit D(R(bci)), store bci -+ x = to_bci(prevBII += x); -+ prevBCI = x; -+ break; -+ case EK_BCO: // OH: transmit D(R(bci)), store D(bci) -+ x = to_bci(prevBII += x) - prevBCI; -+ prevBCI += x; -+ break; -+ } -+ assert(!b.le_bci || prevBCI == to_bci(prevBII)); -+ -+ switch (b.le_len) { -+ case 0: break; -+ case 1: putu1(x); break; -+ case 2: putu2(x); break; -+ case 4: putu4(x); break; -+ default: assert(false); -+ } - } - } - -@@ -2597,7 +2603,7 @@ void unpacker::putlayout(band** body) { - case EK_REPL: - // x is the repeat count - while (x-- > 0) { -- putlayout(b.le_body); -+ putlayout(b.le_body); - } - break; - case EK_UN: -@@ -2606,10 +2612,10 @@ void unpacker::putlayout(band** body) { - break; - case EK_CALL: - { -- band& cble = *b.le_body[0]; -- assert(cble.le_kind == EK_CBLE); -- assert(cble.le_len == b.le_len); -- putlayout(cble.le_body); -+ band& cble = *b.le_body[0]; -+ assert(cble.le_kind == EK_CBLE); -+ assert(cble.le_len == b.le_len); -+ putlayout(cble.le_body); - } - break; - -@@ -2635,7 +2641,7 @@ void unpacker::read_files() { - // FO_IS_CLASS_STUB might be set, causing overlap between classes and files - for (int i = 0; i < file_count; i++) { - if ((file_options.getInt() & FO_IS_CLASS_STUB) != 0) { -- allFiles -= 1; // this one counts as both class and file -+ allFiles -= 1; // this one counts as both class and file - } - } - file_options.rewind(); -@@ -2646,9 +2652,9 @@ void unpacker::read_files() { - - maybe_inline - void unpacker::get_code_header(int& max_stack, -- int& max_na_locals, -- int& handler_count, -- int& cflags) { -+ int& max_na_locals, -+ int& handler_count, -+ int& cflags) { - int sc = code_headers.getByte(); - if (sc == 0) { - max_stack = max_na_locals = handler_count = cflags = -1; -@@ -2801,7 +2807,7 @@ inline // called exactly once => inline - inline // called exactly once => inline - void unpacker::read_bcs() { - printcr(3, "reading compressed bytecodes and operands for %d codes...", -- code_count); -+ code_count); - - // read from bc_codes and bc_case_count - fillbytes all_switch_ops; -@@ -2822,80 +2828,80 @@ void unpacker::read_bcs() { - // Scan one method: - for (;;) { - if (opptr+2 > oplimit) { -- rp = opptr; -- ensure_input(2); -- oplimit = rplimit; -- rp = rp0; // back up -+ rp = opptr; -+ ensure_input(2); -+ oplimit = rplimit; -+ rp = rp0; // back up - } - if (opptr == oplimit) { abort(); break; } - int bc = *opptr++ & 0xFF; - bool isWide = false; - if (bc == bc_wide) { -- if (opptr == oplimit) { abort(); break; } -- bc = *opptr++ & 0xFF; -- isWide = true; -+ if (opptr == oplimit) { abort(); break; } -+ bc = *opptr++ & 0xFF; -+ isWide = true; - } - // Adjust expectations of various band sizes. - switch (bc) { - case bc_tableswitch: - case bc_lookupswitch: -- all_switch_ops.addByte(bc); -- break; -+ all_switch_ops.addByte(bc); -+ break; - case bc_iinc: -- bc_local.expectMoreLength(1); -- bc_which = isWide ? &bc_short : &bc_byte; -- bc_which->expectMoreLength(1); -- break; -+ bc_local.expectMoreLength(1); -+ bc_which = isWide ? &bc_short : &bc_byte; -+ bc_which->expectMoreLength(1); -+ break; - case bc_sipush: -- bc_short.expectMoreLength(1); -- break; -+ bc_short.expectMoreLength(1); -+ break; - case bc_bipush: -- bc_byte.expectMoreLength(1); -- break; -+ bc_byte.expectMoreLength(1); -+ break; - case bc_newarray: -- bc_byte.expectMoreLength(1); -- break; -+ bc_byte.expectMoreLength(1); -+ break; - case bc_multianewarray: -- assert(ref_band_for_op(bc) == &bc_classref); -- bc_classref.expectMoreLength(1); -- bc_byte.expectMoreLength(1); -- break; -+ assert(ref_band_for_op(bc) == &bc_classref); -+ bc_classref.expectMoreLength(1); -+ bc_byte.expectMoreLength(1); -+ break; - case bc_ref_escape: -- bc_escrefsize.expectMoreLength(1); -- bc_escref.expectMoreLength(1); -- break; -+ bc_escrefsize.expectMoreLength(1); -+ bc_escref.expectMoreLength(1); -+ break; - case bc_byte_escape: -- bc_escsize.expectMoreLength(1); -- // bc_escbyte will have to be counted too -- break; -+ bc_escsize.expectMoreLength(1); -+ // bc_escbyte will have to be counted too -+ break; - default: -- if (is_invoke_init_op(bc)) { -- bc_initref.expectMoreLength(1); -- break; -- } -- bc_which = ref_band_for_self_op(bc, isAload, junkBC); -- if (bc_which != null) { -- bc_which->expectMoreLength(1); -- break; -- } -- if (is_branch_op(bc)) { -- bc_label.expectMoreLength(1); -- break; -- } -- bc_which = ref_band_for_op(bc); -- if (bc_which != null) { -- bc_which->expectMoreLength(1); -- assert(bc != bc_multianewarray); // handled elsewhere -- break; -- } -- if (is_local_slot_op(bc)) { -- bc_local.expectMoreLength(1); -- break; -- } -- break; -+ if (is_invoke_init_op(bc)) { -+ bc_initref.expectMoreLength(1); -+ break; -+ } -+ bc_which = ref_band_for_self_op(bc, isAload, junkBC); -+ if (bc_which != null) { -+ bc_which->expectMoreLength(1); -+ break; -+ } -+ if (is_branch_op(bc)) { -+ bc_label.expectMoreLength(1); -+ break; -+ } -+ bc_which = ref_band_for_op(bc); -+ if (bc_which != null) { -+ bc_which->expectMoreLength(1); -+ assert(bc != bc_multianewarray); // handled elsewhere -+ break; -+ } -+ if (is_local_slot_op(bc)) { -+ bc_local.expectMoreLength(1); -+ break; -+ } -+ break; - case bc_end_marker: -- // Increment k and test against code_count. -- goto doneScanningMethod; -+ // Increment k and test against code_count. -+ goto doneScanningMethod; - } - } - doneScanningMethod:{} -@@ -2929,15 +2935,15 @@ void unpacker::read_bcs() { - bc_escbyte.readData(bc_escsize.getIntTotal()); - - printcr(3, "scanned %d opcode and %d operand bytes for %d codes...", -- (int)(bc_codes.size()), -- (int)(bc_escsize.maxRP() - bc_case_value.minRP()), -- code_count); -+ (int)(bc_codes.size()), -+ (int)(bc_escsize.maxRP() - bc_case_value.minRP()), -+ code_count); - } - - void unpacker::read_bands() { - byte* rp0 = rp; - int i; -- -+ CHECK; - read_file_header(); - CHECK; - -@@ -3063,8 +3069,8 @@ void cpool::expandSignatures() { - int c = form.ptr[j]; - buf.addByte(c); - if (c == 'L') { -- entry* cls = e.refs[refnum++]; -- buf.append(cls->className()->asUtf8()); -+ entry* cls = e.refs[refnum++]; -+ buf.append(cls->className()->asUtf8()); - } - } - assert(refnum == e.nrefs); -@@ -3099,7 +3105,7 @@ void cpool::expandSignatures() { - for (int j = 0; j < e.nrefs; j++) { - entry*& e2 = e.refs[j]; - if (e2 != null && e2->tag == CONSTANT_Signature) -- e2 = e2->refs[0]; -+ e2 = e2->refs[0]; - } - } - } -@@ -3141,14 +3147,14 @@ void cpool::initMemberIndexes() { - int fc = field_counts[i]; - int mc = method_counts[i]; - all_indexes[i*2+0].init(fc, field_ix+fbase, -- CONSTANT_Fieldref + SUBINDEX_BIT); -+ CONSTANT_Fieldref + SUBINDEX_BIT); - all_indexes[i*2+1].init(mc, method_ix+mbase, -- CONSTANT_Methodref + SUBINDEX_BIT); -+ CONSTANT_Methodref + SUBINDEX_BIT); - // reuse field_counts and member_counts as fill pointers: - field_counts[i] = fbase; - method_counts[i] = mbase; - printcr(3, "class %d fields @%d[%d] methods @%d[%d]", -- i, fbase, fc, mbase, mc); -+ i, fbase, fc, mbase, mc); - fbase += fc+1; - mbase += mc+1; - // (the +1 leaves a space between every subarray) -@@ -3178,7 +3184,7 @@ void cpool::initMemberIndexes() { - cpindex* fix = getFieldIndex(cls); - cpindex* mix = getMethodIndex(cls); - printcr(2, "field and method index for %s [%d] [%d]", -- cls->string(), mix->len, fix->len); -+ cls->string(), mix->len, fix->len); - prevord = -1; - for (j = 0, len = fix->len; j < len; j++) { - entry* f = fix->get(j); -@@ -3204,7 +3210,7 @@ void cpool::initMemberIndexes() { - } - assert(fvisited == nfields); - assert(mvisited == nmethods); --#endif -+#endif - - // Free intermediate buffers. - u->free_temps(); -@@ -3438,8 +3444,8 @@ bool unpacker::set_option(const char* pr - bool unpacker::set_option(const char* prop, const char* value) { - if (prop == NULL) return false; - if (strcmp(prop, UNPACK_DEFLATE_HINT) == 0) { -- deflate_hint_or_zero = ( (value == null || strcmp(value, "keep") == 0) -- ? 0: BOOL_TF(value) ? +1: -1); -+ deflate_hint_or_zero = ( (value == null || strcmp(value, "keep") == 0) -+ ? 0: BOOL_TF(value) ? +1: -1); - #ifdef HAVE_STRIP - } else if (strcmp(prop, UNPACK_STRIP_COMPILE) == 0) { - strip_compile = STR_TF(value); -@@ -3466,7 +3472,7 @@ bool unpacker::set_option(const char* pr - } else { - modification_time_or_zero = atoi(value); - if (modification_time_or_zero == 0) -- modification_time_or_zero = 1; // make non-zero -+ modification_time_or_zero = 1; // make non-zero - } - } else if (strcmp(prop, UNPACK_LOG_FILE) == 0) { - log_file = (value == null)? value: saveStr(value); -@@ -3597,14 +3603,16 @@ void unpacker::dump_options() { - - - // Usage: unpack a byte buffer --// packptr is a reference to byte buffer containing a -+// packptr is a reference to byte buffer containing a - // packed file and len is the length of the buffer. - // If null, the callback is used to fill an internal buffer. - void unpacker::start(void* packptr, size_t len) { -+ CHECK; - NOT_PRODUCT(debug_u = this); - if (packptr != null && len != 0) { - inbytes.set((byte*) packptr, len); - } -+ CHECK; - read_bands(); - } - -@@ -3735,6 +3743,7 @@ void unpacker::write_bc_ops() { - NOT_PRODUCT(bc_superfield.setIndex(null)); - NOT_PRODUCT(bc_supermethod.setIndex(null)); - } -+ CHECK; - - for (int curIP = 0; ; curIP++) { - int curPC = wpoffset() - codeBase; -@@ -3760,196 +3769,197 @@ void unpacker::write_bc_ops() { - case bc_tableswitch: // apc: (df, lo, hi, (hi-lo+1)*(label)) - case bc_lookupswitch: // apc: (df, nc, nc*(case, label)) - { -- int caseCount = bc_case_count.getInt(); -- while (((wpoffset() - codeBase) % 4) != 0) putu1_fast(0); -- ensure_put_space(30 + caseCount*8); -- put_label(curIP, 4); //int df = bc_label.getInt(); -- if (bc == bc_tableswitch) { -- int lo = bc_case_value.getInt(); -- int hi = lo + caseCount-1; -- putu4(lo); -- putu4(hi); -- for (int j = 0; j < caseCount; j++) { -- put_label(curIP, 4); //int lVal = bc_label.getInt(); -- //int cVal = lo + j; -- } -- } else { -- putu4(caseCount); -- for (int j = 0; j < caseCount; j++) { -- int cVal = bc_case_value.getInt(); -- putu4(cVal); -- put_label(curIP, 4); //int lVal = bc_label.getInt(); -- } -- } -- assert(to_bci(curIP) == curPC); -- continue; -+ int caseCount = bc_case_count.getInt(); -+ while (((wpoffset() - codeBase) % 4) != 0) putu1_fast(0); -+ ensure_put_space(30 + caseCount*8); -+ put_label(curIP, 4); //int df = bc_label.getInt(); -+ if (bc == bc_tableswitch) { -+ int lo = bc_case_value.getInt(); -+ int hi = lo + caseCount-1; -+ putu4(lo); -+ putu4(hi); -+ for (int j = 0; j < caseCount; j++) { -+ put_label(curIP, 4); //int lVal = bc_label.getInt(); -+ //int cVal = lo + j; -+ } -+ } else { -+ putu4(caseCount); -+ for (int j = 0; j < caseCount; j++) { -+ int cVal = bc_case_value.getInt(); -+ putu4(cVal); -+ put_label(curIP, 4); //int lVal = bc_label.getInt(); -+ } -+ } -+ assert(to_bci(curIP) == curPC); -+ continue; - } - case bc_iinc: - { -- int local = bc_local.getInt(); -- int delta = (isWide ? bc_short : bc_byte).getInt(); -- if (isWide) { -- putu2(local); -- putu2(delta); -- } else { -- putu1_fast(local); -- putu1_fast(delta); -- } -- continue; -+ int local = bc_local.getInt(); -+ int delta = (isWide ? bc_short : bc_byte).getInt(); -+ if (isWide) { -+ putu2(local); -+ putu2(delta); -+ } else { -+ putu1_fast(local); -+ putu1_fast(delta); -+ } -+ continue; - } - case bc_sipush: - { -- int val = bc_short.getInt(); -- putu2(val); -- continue; -+ int val = bc_short.getInt(); -+ putu2(val); -+ continue; - } - case bc_bipush: - case bc_newarray: - { -- int val = bc_byte.getByte(); -- putu1_fast(val); -- continue; -+ int val = bc_byte.getByte(); -+ putu1_fast(val); -+ continue; - } - case bc_ref_escape: - { -- // Note that insnMap has one entry for this. -+ // Note that insnMap has one entry for this. - --wp; // not really part of the code -- int size = bc_escrefsize.getInt(); -- entry* ref = bc_escref.getRefN(); -- CHECK; -- switch (size) { -- case 1: putu1ref(ref); break; -- case 2: putref(ref); break; -- default: assert(false); -- } -- continue; -+ int size = bc_escrefsize.getInt(); -+ entry* ref = bc_escref.getRefN(); -+ CHECK; -+ switch (size) { -+ case 1: putu1ref(ref); break; -+ case 2: putref(ref); break; -+ default: assert(false); -+ } -+ continue; - } - case bc_byte_escape: - { -- // Note that insnMap has one entry for all these bytes. -+ // Note that insnMap has one entry for all these bytes. - --wp; // not really part of the code -- int size = bc_escsize.getInt(); -- ensure_put_space(size); -- for (int j = 0; j < size; j++) -- putu1_fast(bc_escbyte.getByte()); -- continue; -+ int size = bc_escsize.getInt(); -+ ensure_put_space(size); -+ for (int j = 0; j < size; j++) -+ putu1_fast(bc_escbyte.getByte()); -+ continue; - } - default: - if (is_invoke_init_op(bc)) { -- origBC = bc_invokespecial; -- entry* classRef; -- switch (bc - _invokeinit_op) { -- case _invokeinit_self_option: classRef = thisClass; break; -- case _invokeinit_super_option: classRef = superClass; break; -- default: assert(bc == _invokeinit_op+_invokeinit_new_option); -- case _invokeinit_new_option: classRef = newClass; break; -- } -- wp[-1] = origBC; // overwrite with origBC -- int coding = bc_initref.getInt(); -- // Find the nth overloading of <init> in classRef. -- entry* ref = null; -- cpindex* ix = (classRef == null)? null: cp.getMethodIndex(classRef); -- for (int j = 0, which_init = 0; ; j++) { -- ref = (ix == null)? null: ix->get(j); -- if (ref == null) break; // oops, bad input -- assert(ref->tag == CONSTANT_Methodref); -- if (ref->memberDescr()->descrName() == cp.sym[cpool::s_lt_init_gt]) { -- if (which_init++ == coding) break; -- } -- } -- putref(ref); -- continue; -+ origBC = bc_invokespecial; -+ entry* classRef; -+ switch (bc - _invokeinit_op) { -+ case _invokeinit_self_option: classRef = thisClass; break; -+ case _invokeinit_super_option: classRef = superClass; break; -+ default: assert(bc == _invokeinit_op+_invokeinit_new_option); -+ case _invokeinit_new_option: classRef = newClass; break; -+ } -+ wp[-1] = origBC; // overwrite with origBC -+ int coding = bc_initref.getInt(); -+ // Find the nth overloading of <init> in classRef. -+ entry* ref = null; -+ cpindex* ix = cp.getMethodIndex(classRef); -+ CHECK; -+ for (int j = 0, which_init = 0; ; j++) { -+ ref = (ix == null)? null: ix->get(j); -+ if (ref == null) break; // oops, bad input -+ assert(ref->tag == CONSTANT_Methodref); -+ if (ref->memberDescr()->descrName() == cp.sym[cpool::s_lt_init_gt]) { -+ if (which_init++ == coding) break; -+ } -+ } -+ putref(ref); -+ continue; - } - bc_which = ref_band_for_self_op(bc, isAload, origBC); - if (bc_which != null) { -- if (!isAload) { -- wp[-1] = origBC; // overwrite with origBC -- } else { -- wp[-1] = bc_aload_0; // overwrite with _aload_0 -- // Note: insnMap keeps the _aload_0 separate. -- bcimap.add(++curPC); -- ++curIP; -- putu1_fast(origBC); -- } -- entry* ref = bc_which->getRef(); -- CHECK; -- putref(ref); -- continue; -+ if (!isAload) { -+ wp[-1] = origBC; // overwrite with origBC -+ } else { -+ wp[-1] = bc_aload_0; // overwrite with _aload_0 -+ // Note: insnMap keeps the _aload_0 separate. -+ bcimap.add(++curPC); -+ ++curIP; -+ putu1_fast(origBC); -+ } -+ entry* ref = bc_which->getRef(); -+ CHECK; -+ putref(ref); -+ continue; - } - if (is_branch_op(bc)) { -- //int lVal = bc_label.getInt(); -- if (bc < bc_goto_w) { -- put_label(curIP, 2); //putu2(lVal & 0xFFFF); -- } else { -- assert(bc <= bc_jsr_w); -- put_label(curIP, 4); //putu4(lVal); -- } -- assert(to_bci(curIP) == curPC); -- continue; -+ //int lVal = bc_label.getInt(); -+ if (bc < bc_goto_w) { -+ put_label(curIP, 2); //putu2(lVal & 0xFFFF); -+ } else { -+ assert(bc <= bc_jsr_w); -+ put_label(curIP, 4); //putu4(lVal); -+ } -+ assert(to_bci(curIP) == curPC); -+ continue; - } - bc_which = ref_band_for_op(bc); - if (bc_which != null) { -- entry* ref = bc_which->getRefCommon(bc_which->ix, bc_which->nullOK); -- CHECK; -- if (ref == null && bc_which == &bc_classref) { -- // Shorthand for class self-references. -- ref = thisClass; -- } -- origBC = bc; -- switch (bc) { -- case bc_ildc: -- case bc_cldc: -- case bc_fldc: -- case bc_aldc: -- origBC = bc_ldc; -- break; -- case bc_ildc_w: -- case bc_cldc_w: -- case bc_fldc_w: -- case bc_aldc_w: -- origBC = bc_ldc_w; -- break; -- case bc_lldc2_w: -- case bc_dldc2_w: -- origBC = bc_ldc2_w; -- break; -- case bc_new: -- newClass = ref; -- break; -- } -- wp[-1] = origBC; // overwrite with origBC -- if (origBC == bc_ldc) { -- putu1ref(ref); -- } else { -- putref(ref); -- } -- if (origBC == bc_multianewarray) { -- // Copy the trailing byte also. -- int val = bc_byte.getByte(); -- putu1_fast(val); -- } else if (origBC == bc_invokeinterface) { -- int argSize = ref->memberDescr()->descrType()->typeSize(); -- putu1_fast(1 + argSize); -- putu1_fast(0); -- } -- continue; -+ entry* ref = bc_which->getRefCommon(bc_which->ix, bc_which->nullOK); -+ CHECK; -+ if (ref == null && bc_which == &bc_classref) { -+ // Shorthand for class self-references. -+ ref = thisClass; -+ } -+ origBC = bc; -+ switch (bc) { -+ case bc_ildc: -+ case bc_cldc: -+ case bc_fldc: -+ case bc_aldc: -+ origBC = bc_ldc; -+ break; -+ case bc_ildc_w: -+ case bc_cldc_w: -+ case bc_fldc_w: -+ case bc_aldc_w: -+ origBC = bc_ldc_w; -+ break; -+ case bc_lldc2_w: -+ case bc_dldc2_w: -+ origBC = bc_ldc2_w; -+ break; -+ case bc_new: -+ newClass = ref; -+ break; -+ } -+ wp[-1] = origBC; // overwrite with origBC -+ if (origBC == bc_ldc) { -+ putu1ref(ref); -+ } else { -+ putref(ref); -+ } -+ if (origBC == bc_multianewarray) { -+ // Copy the trailing byte also. -+ int val = bc_byte.getByte(); -+ putu1_fast(val); -+ } else if (origBC == bc_invokeinterface) { -+ int argSize = ref->memberDescr()->descrType()->typeSize(); -+ putu1_fast(1 + argSize); -+ putu1_fast(0); -+ } -+ continue; - } - if (is_local_slot_op(bc)) { -- int local = bc_local.getInt(); -- if (isWide) { -- putu2(local); -- if (bc == bc_iinc) { -- int iVal = bc_short.getInt(); -- putu2(iVal); -- } -- } else { -- putu1_fast(local); -- if (bc == bc_iinc) { -- int iVal = bc_byte.getByte(); -- putu1_fast(iVal); -- } -- } -- continue; -+ int local = bc_local.getInt(); -+ if (isWide) { -+ putu2(local); -+ if (bc == bc_iinc) { -+ int iVal = bc_short.getInt(); -+ putu2(iVal); -+ } -+ } else { -+ putu1_fast(local); -+ if (bc == bc_iinc) { -+ int iVal = bc_byte.getByte(); -+ putu1_fast(iVal); -+ } -+ } -+ continue; - } - // Random bytecode. Just copy it. - assert(bc < bc_bytecode_limit); -@@ -4073,78 +4083,80 @@ int unpacker::write_attrs(int attrc, jul - case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_OVERFLOW): - case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_OVERFLOW): - case ADH_BYTE(ATTR_CONTEXT_CODE, X_ATTR_OVERFLOW): -- // no attribute at all, so back up on this one -- wp = wp_at(abase); -- continue; -+ // no attribute at all, so back up on this one -+ wp = wp_at(abase); -+ continue; - - case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_ClassFile_version): -- cur_class_minver = class_ClassFile_version_minor_H.getInt(); -- cur_class_majver = class_ClassFile_version_major_H.getInt(); -- // back up; not a real attribute -- wp = wp_at(abase); -- continue; -+ cur_class_minver = class_ClassFile_version_minor_H.getInt(); -+ cur_class_majver = class_ClassFile_version_major_H.getInt(); -+ // back up; not a real attribute -+ wp = wp_at(abase); -+ continue; - - case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_InnerClasses): -- // note the existence of this attr, but save for later -- if (cur_class_has_local_ics) -- abort("too many InnerClasses attrs"); -- cur_class_has_local_ics = true; -- wp = wp_at(abase); -- continue; -+ // note the existence of this attr, but save for later -+ if (cur_class_has_local_ics) -+ abort("too many InnerClasses attrs"); -+ cur_class_has_local_ics = true; -+ wp = wp_at(abase); -+ continue; - - case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_SourceFile): -- aname = cp.sym[cpool::s_SourceFile]; -- ref = class_SourceFile_RUN.getRefN(); -- CHECK_0; -- if (ref == null) { -- bytes& n = cur_class->ref(0)->value.b; -- // parse n = (<pkg>/)*<outer>?($<id>)* -- int pkglen = lastIndexOf(SLASH_MIN, SLASH_MAX, n, n.len)+1; -- bytes prefix = n.slice(pkglen, n.len); -- for (;;) { -- // Work backwards, finding all '$', '#', etc. -- int dollar = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, prefix, prefix.len); -- if (dollar < 0) break; -- prefix = prefix.slice(0, dollar); -- } -- const char* suffix = ".java"; -- int len = prefix.len + strlen(suffix); -- bytes name; name.set(T_NEW(byte, add_size(len, 1)), len); -- name.strcat(prefix).strcat(suffix); -- ref = cp.ensureUtf8(name); -- } -- putref(ref); -- break; -+ aname = cp.sym[cpool::s_SourceFile]; -+ ref = class_SourceFile_RUN.getRefN(); -+ CHECK_0; -+ if (ref == null) { -+ bytes& n = cur_class->ref(0)->value.b; -+ // parse n = (<pkg>/)*<outer>?($<id>)* -+ int pkglen = lastIndexOf(SLASH_MIN, SLASH_MAX, n, n.len)+1; -+ bytes prefix = n.slice(pkglen, n.len); -+ for (;;) { -+ // Work backwards, finding all '$', '#', etc. -+ int dollar = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, prefix, prefix.len); -+ if (dollar < 0) break; -+ prefix = prefix.slice(0, dollar); -+ } -+ const char* suffix = ".java"; -+ int len = prefix.len + strlen(suffix); -+ bytes name; name.set(T_NEW(byte, add_size(len, 1)), len); -+ name.strcat(prefix).strcat(suffix); -+ ref = cp.ensureUtf8(name); -+ } -+ putref(ref); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_EnclosingMethod): -- aname = cp.sym[cpool::s_EnclosingMethod]; -- putref(class_EnclosingMethod_RC.getRefN()); -- putref(class_EnclosingMethod_RDN.getRefN()); -- break; -+ aname = cp.sym[cpool::s_EnclosingMethod]; -+ putref(class_EnclosingMethod_RC.getRefN()); -+ CHECK_0; -+ putref(class_EnclosingMethod_RDN.getRefN()); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_FIELD, FIELD_ATTR_ConstantValue): -- aname = cp.sym[cpool::s_ConstantValue]; -- putref(field_ConstantValue_KQ.getRefUsing(cp.getKQIndex())); -- break; -+ aname = cp.sym[cpool::s_ConstantValue]; -+ putref(field_ConstantValue_KQ.getRefUsing(cp.getKQIndex())); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_METHOD, METHOD_ATTR_Code): -- aname = cp.sym[cpool::s_Code]; -- write_code(); -- break; -+ aname = cp.sym[cpool::s_Code]; -+ write_code(); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_METHOD, METHOD_ATTR_Exceptions): -- aname = cp.sym[cpool::s_Exceptions]; -- putu2(count = method_Exceptions_N.getInt()); -- for (j = 0; j < count; j++) { -- putref(method_Exceptions_RC.getRefN()); -- } -- break; -+ aname = cp.sym[cpool::s_Exceptions]; -+ putu2(count = method_Exceptions_N.getInt()); -+ for (j = 0; j < count; j++) { -+ putref(method_Exceptions_RC.getRefN()); -+ CHECK_0; -+ } -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_StackMapTable): -- aname = cp.sym[cpool::s_StackMapTable]; -+ aname = cp.sym[cpool::s_StackMapTable]; - // (keep this code aligned with its brother in unpacker::read_attrs) -- putu2(count = code_StackMapTable_N.getInt()); -- for (j = 0; j < count; j++) { -+ putu2(count = code_StackMapTable_N.getInt()); -+ for (j = 0; j < count; j++) { - int tag = code_StackMapTable_frame_T.getByte(); - putu1(tag); - if (tag <= 127) { -@@ -4160,109 +4172,115 @@ int unpacker::write_attrs(int attrc, jul - // (253) [(1)(2)(2)] - // (254) [(1)(2)(2)(2)] - putu2(code_StackMapTable_offset.getInt()); -+ CHECK_0; - for (int j2 = (tag - 251); j2 > 0; j2--) { - put_stackmap_type(); -+ CHECK_0; - } - } else { - // (255) [(1)NH[(2)]NH[(2)]] - putu2(code_StackMapTable_offset.getInt()); - putu2(j2 = code_StackMapTable_local_N.getInt()); -- while (j2-- > 0) put_stackmap_type(); -+ while (j2-- > 0) {put_stackmap_type(); CHECK_0;} - putu2(j2 = code_StackMapTable_stack_N.getInt()); -- while (j2-- > 0) put_stackmap_type(); -+ while (j2-- > 0) {put_stackmap_type(); CHECK_0;} - } -- } -- break; -+ } -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LineNumberTable): -- aname = cp.sym[cpool::s_LineNumberTable]; -- putu2(count = code_LineNumberTable_N.getInt()); -- for (j = 0; j < count; j++) { -- putu2(to_bci(code_LineNumberTable_bci_P.getInt())); -- putu2(code_LineNumberTable_line.getInt()); -- } -- break; -+ aname = cp.sym[cpool::s_LineNumberTable]; -+ putu2(count = code_LineNumberTable_N.getInt()); -+ for (j = 0; j < count; j++) { -+ putu2(to_bci(code_LineNumberTable_bci_P.getInt())); -+ putu2(code_LineNumberTable_line.getInt()); -+ } -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LocalVariableTable): -- aname = cp.sym[cpool::s_LocalVariableTable]; -- putu2(count = code_LocalVariableTable_N.getInt()); -- for (j = 0; j < count; j++) { -- int bii = code_LocalVariableTable_bci_P.getInt(); -- int bci = to_bci(bii); -- putu2(bci); -- bii += code_LocalVariableTable_span_O.getInt(); -- putu2(to_bci(bii) - bci); -- putref(code_LocalVariableTable_name_RU.getRefN()); -- putref(code_LocalVariableTable_type_RS.getRefN()); -- putu2(code_LocalVariableTable_slot.getInt()); -- } -- break; -+ aname = cp.sym[cpool::s_LocalVariableTable]; -+ putu2(count = code_LocalVariableTable_N.getInt()); -+ for (j = 0; j < count; j++) { -+ int bii = code_LocalVariableTable_bci_P.getInt(); -+ int bci = to_bci(bii); -+ putu2(bci); -+ bii += code_LocalVariableTable_span_O.getInt(); -+ putu2(to_bci(bii) - bci); -+ putref(code_LocalVariableTable_name_RU.getRefN()); -+ CHECK_0; -+ putref(code_LocalVariableTable_type_RS.getRefN()); -+ CHECK_0; -+ putu2(code_LocalVariableTable_slot.getInt()); -+ } -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LocalVariableTypeTable): -- aname = cp.sym[cpool::s_LocalVariableTypeTable]; -- putu2(count = code_LocalVariableTypeTable_N.getInt()); -- for (j = 0; j < count; j++) { -- int bii = code_LocalVariableTypeTable_bci_P.getInt(); -- int bci = to_bci(bii); -- putu2(bci); -- bii += code_LocalVariableTypeTable_span_O.getInt(); -- putu2(to_bci(bii) - bci); -- putref(code_LocalVariableTypeTable_name_RU.getRefN()); -- putref(code_LocalVariableTypeTable_type_RS.getRefN()); -- putu2(code_LocalVariableTypeTable_slot.getInt()); -- } -- break; -+ aname = cp.sym[cpool::s_LocalVariableTypeTable]; -+ putu2(count = code_LocalVariableTypeTable_N.getInt()); -+ for (j = 0; j < count; j++) { -+ int bii = code_LocalVariableTypeTable_bci_P.getInt(); -+ int bci = to_bci(bii); -+ putu2(bci); -+ bii += code_LocalVariableTypeTable_span_O.getInt(); -+ putu2(to_bci(bii) - bci); -+ putref(code_LocalVariableTypeTable_name_RU.getRefN()); -+ CHECK_0; -+ putref(code_LocalVariableTypeTable_type_RS.getRefN()); -+ CHECK_0; -+ putu2(code_LocalVariableTypeTable_slot.getInt()); -+ } -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CLASS, X_ATTR_Signature): -- aname = cp.sym[cpool::s_Signature]; -- putref(class_Signature_RS.getRefN()); -- break; -+ aname = cp.sym[cpool::s_Signature]; -+ putref(class_Signature_RS.getRefN()); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_Signature): -- aname = cp.sym[cpool::s_Signature]; -- putref(field_Signature_RS.getRefN()); -- break; -+ aname = cp.sym[cpool::s_Signature]; -+ putref(field_Signature_RS.getRefN()); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_Signature): -- aname = cp.sym[cpool::s_Signature]; -- putref(method_Signature_RS.getRefN()); -- break; -+ aname = cp.sym[cpool::s_Signature]; -+ putref(method_Signature_RS.getRefN()); -+ break; - - case ADH_BYTE(ATTR_CONTEXT_CLASS, X_ATTR_Deprecated): - case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_Deprecated): - case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_Deprecated): -- aname = cp.sym[cpool::s_Deprecated]; -- // no data -- break; -- } -- } -- -+ aname = cp.sym[cpool::s_Deprecated]; -+ // no data -+ break; -+ } -+ } -+ CHECK_0; - if (aname == null) { - // Unparse a compressor-defined attribute. - layout_definition* lo = ad.getLayout(idx); - if (lo == null) { -- abort("bad layout index"); -- break; -+ abort("bad layout index"); -+ break; - } - assert(lo->idx == idx); - aname = lo->nameEntry; - if (aname == null) { -- bytes nameb; nameb.set(lo->name); -- aname = cp.ensureUtf8(nameb); -- // Cache the name entry for next time. -- lo->nameEntry = aname; -+ bytes nameb; nameb.set(lo->name); -+ aname = cp.ensureUtf8(nameb); -+ // Cache the name entry for next time. -+ lo->nameEntry = aname; - } - // Execute all the layout elements. - band** bands = lo->bands(); - if (lo->hasCallables()) { -- band& cble = *bands[0]; -- assert(cble.le_kind == EK_CBLE); -- bands = cble.le_body; -+ band& cble = *bands[0]; -+ assert(cble.le_kind == EK_CBLE); -+ bands = cble.le_body; - } - putlayout(bands); - } - -- if (aname == null) -+ if (aname == null) - abort("bad attribute index"); - CHECK_0; - -@@ -4335,8 +4353,8 @@ void unpacker::write_classfile_tail() { - julong indexMask = ad.flagIndexMask(); - - cur_class = class_this.getRef(); -+ CHECK; - cur_super = class_super.getRef(); -- - CHECK; - - if (cur_super == cur_class) cur_super = null; -@@ -4349,6 +4367,7 @@ void unpacker::write_classfile_tail() { - putu2(num = class_interface_count.getInt()); - for (i = 0; i < num; i++) { - putref(class_interface.getRef()); -+ CHECK; - } - - write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD); -@@ -4389,8 +4408,8 @@ void unpacker::write_classfile_tail() { - entry& e = *oes[i]; - if (e.tag != CONSTANT_Class) continue; // wrong sort - for (inner_class* ic = cp.getIC(&e); -- ic != null; -- ic = cp.getIC(ic->outer)) { -+ ic != null; -+ ic = cp.getIC(ic->outer)) { - if (ic->requested) break; // already processed - ic->requested = true; - requested_ics.add(ic); -@@ -4421,22 +4440,24 @@ void unpacker::write_classfile_tail() { - if (flags == 0) { - // The extra IC is simply a copy of a global IC. - if (global_ic == null) { -- abort("bad reference to inner class"); -- break; -+ abort("bad reference to inner class"); -+ break; - } - extra_ic = (*global_ic); // fill in rest of fields - } else { - flags &= ~ACC_IC_LONG_FORM; // clear high bit if set to get clean zero - extra_ic.flags = flags; - extra_ic.outer = class_InnerClasses_outer_RCN.getRefN(); -+ CHECK; - extra_ic.name = class_InnerClasses_name_RUN.getRefN(); -+ CHECK; - // Detect if this is an exact copy of the global tuple. - if (global_ic != null) { -- if (global_ic->flags != extra_ic.flags || -- global_ic->outer != extra_ic.outer || -- global_ic->name != extra_ic.name) { -- global_ic = null; // not really the same, so break the link -- } -+ if (global_ic->flags != extra_ic.flags || -+ global_ic->outer != extra_ic.outer || -+ global_ic->name != extra_ic.name) { -+ global_ic = null; // not really the same, so break the link -+ } - } - } - if (global_ic != null && global_ic->requested) { -@@ -4465,15 +4486,15 @@ void unpacker::write_classfile_tail() { - for (i = -num_global_ics; i < num_extra_ics; i++) { - inner_class* ic; - if (i < 0) -- ic = (inner_class*) requested_ics.get(num_global_ics+i); -+ ic = (inner_class*) requested_ics.get(num_global_ics+i); - else -- ic = &extra_ics[i]; -+ ic = &extra_ics[i]; - if (ic->requested) { -- putref(ic->inner); -- putref(ic->outer); -- putref(ic->name); -- putu2(ic->flags); -- NOT_PRODUCT(local_ics--); -+ putref(ic->inner); -+ putref(ic->outer); -+ putref(ic->name); -+ putu2(ic->flags); -+ NOT_PRODUCT(local_ics--); - } - } - assert(local_ics == 0); // must balance -@@ -4573,7 +4594,7 @@ unpacker::file* unpacker::get_next_file( - if (archive_size != 0) { - julong predicted_size = unsized_bytes_read + archive_size; - if (predicted_size != bytes_read) -- abort("archive header had incorrect size"); -+ abort("archive header had incorrect size"); - } - return null; - } -@@ -4637,7 +4658,7 @@ unpacker::file* unpacker::get_next_file( - size_t rpleft = input_remaining(); - if (rpleft > 0) { - if (rpleft > cur_file.size) -- rpleft = (size_t) cur_file.size; -+ rpleft = (size_t) cur_file.size; - cur_file.data[0].set(rp, rpleft); - rp += rpleft; - } -@@ -4655,7 +4676,7 @@ unpacker::file* unpacker::get_next_file( - - // Write a file to jarout. - void unpacker::write_file_to_jar(unpacker::file* f) { -- size_t htsize = f->data[0].len + f->data[1].len; -+ size_t htsize = f->data[0].len + f->data[1].len; - julong fsize = f->size; - #ifndef PRODUCT - if (nowrite NOT_PRODUCT(|| skipfiles-- > 0)) { -@@ -4665,7 +4686,7 @@ void unpacker::write_file_to_jar(unpacke - #endif - if (htsize == fsize) { - jarout->addJarEntry(f->name, f->deflate_hint(), f->modtime, -- f->data[0], f->data[1]); -+ f->data[0], f->data[1]); - } else { - assert(input_remaining() == 0); - bytes part1, part2; -@@ -4680,27 +4701,27 @@ void unpacker::write_file_to_jar(unpacke - if (fleft > 0) { - // Must read some more. - if (live_input) { -- // Stop using the input buffer. Make a new one: -- if (free_input) input.free(); -- input.init(fleft > (1<<12) ? fleft : (1<<12)); -- free_input = true; -- live_input = false; -+ // Stop using the input buffer. Make a new one: -+ if (free_input) input.free(); -+ input.init(fleft > (1<<12) ? fleft : (1<<12)); -+ free_input = true; -+ live_input = false; - } else { -- // Make it large enough. -- assert(free_input); // must be reallocable -- input.ensureSize(fleft); -+ // Make it large enough. -+ assert(free_input); // must be reallocable -+ input.ensureSize(fleft); - } - rplimit = rp = input.base(); - CHECK; - input.setLimit(rp + fleft); - if (!ensure_input(fleft)) -- abort("EOF reading resource file"); -+ abort("EOF reading resource file"); - part2.ptr = input_scan(); - part2.len = input_remaining(); - rplimit = rp = input.base(); - } - jarout->addJarEntry(f->name, f->deflate_hint(), f->modtime, -- part1, part2); -+ part1, part2); - } - if (verbose >= 3) { - fprintf(errstrm, "Wrote %lld bytes to: %s\n", fsize, f->name); -@@ -4722,7 +4743,7 @@ void unpacker::redirect_stdio() { - } else if (strcmp(log_file, LOGFILE_STDOUT) == 0) { - errstrm = stdout; - return; -- } else if (log_file[0] != '\0' && (errstrm = fopen(log_file,"a+")) != NULL) { -+ } else if (log_file[0] != '\0' && (errstrm = fopen(log_file,"a+")) != NULL) { - return; - } else { - char log_file_name[PATH_MAX+100]; -@@ -4732,7 +4753,7 @@ void unpacker::redirect_stdio() { - if (n < 1 || n > PATH_MAX) { - sprintf(tmpdir,"C:\\"); - } -- sprintf(log_file_name, "%sunpack.log", tmpdir); -+ sprintf(log_file_name, "%sunpack.log", tmpdir); - #else - sprintf(tmpdir,"/tmp"); - sprintf(log_file_name, "/tmp/unpack.log"); -@@ -4742,7 +4763,7 @@ void unpacker::redirect_stdio() { - return ; - } - -- char *tname = tempnam(tmpdir,"#upkg"); -+ char *tname = tempnam(tmpdir,"#upkg"); - sprintf(log_file_name, "%s", tname); - if ((errstrm = fopen(log_file_name, "a+")) != NULL) { - log_file = errstrm_name = saveStr(log_file_name); -@@ -4758,7 +4779,7 @@ void unpacker::redirect_stdio() { - #endif - // Last resort - // (Do not use stdout, since it might be jarout->jarfp.) -- errstrm = stderr; -+ errstrm = stderr; - log_file = errstrm_name = LOGFILE_STDERR; - } - } -@@ -4799,3 +4820,5 @@ void unpacker::abort(const char* message - #endif - #endif // JNI - } -+ -+ |