src/java.base/share/classes/com/sun/java/util/jar/pack/PackageWriter.java
author rriggs
Fri, 07 Dec 2018 11:51:17 -0500
changeset 52902 e3398b2e1ab0
parent 47216 71c04702a3d5
permissions -rw-r--r--
8214971: Replace use of string.equals("") with isEmpty() Reviewed-by: jlaskey, prappo, lancea, dfuchs, redestad
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
15261
c5b882836677 8005252: pack200 should support MethodParameters
ksrini
parents: 13795
diff changeset
     2
 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4919
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4919
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4919
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4919
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4919
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package com.sun.java.util.jar.pack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
    28
import com.sun.java.util.jar.pack.ConstantPool.*;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import com.sun.java.util.jar.pack.Package.Class;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import com.sun.java.util.jar.pack.Package.File;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import com.sun.java.util.jar.pack.Package.InnerClass;
7192
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 5506
diff changeset
    32
import java.io.IOException;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 5506
diff changeset
    33
import java.io.OutputStream;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 5506
diff changeset
    34
import java.io.PrintStream;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 5506
diff changeset
    35
import java.util.ArrayList;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 5506
diff changeset
    36
import java.util.Arrays;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 5506
diff changeset
    37
import java.util.Comparator;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 5506
diff changeset
    38
import java.util.HashMap;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 5506
diff changeset
    39
import java.util.HashSet;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 5506
diff changeset
    40
import java.util.List;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 5506
diff changeset
    41
import java.util.Map;
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
    42
import java.util.Set;
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
    43
import static com.sun.java.util.jar.pack.Constants.*;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * Writer for a package file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * @author John Rose
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
class PackageWriter extends BandStructure {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    Package pkg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    OutputStream finalOut;
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
    52
    Package.Version packageVersion;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    PackageWriter(Package pkg, OutputStream out) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
        this.pkg = pkg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
        this.finalOut = out;
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
    57
        // Caller has specified maximum class file version in the package:
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
    58
        initHighestClassVersion(pkg.getHighestClassVersion());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    void write() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
        boolean ok = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
            if (verbose > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
                Utils.log.info("Setting up constant pool...");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
            setup();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
            if (verbose > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
                Utils.log.info("Packing...");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
            // writeFileHeader() is done last, since it has ultimate counts
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
            // writeBandHeaders() is called after all other bands are done
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
            writeConstantPool();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
            writeFiles();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
            writeAttrDefs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
            writeInnerClasses();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
            writeClassesAndByteCodes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
            writeAttrCounts();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
            if (verbose > 1)  printCodeHist();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
            // choose codings (fill band_headers if needed)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
            if (verbose > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
                Utils.log.info("Coding...");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
            all_bands.chooseBandCodings();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
            // now we can write the headers:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
            writeFileHeader();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
            writeAllBandsTo(finalOut);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
            ok = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        } catch (Exception ee) {
4919
b00f729ee70a 6925868: Eliminate pack200's dependency on logging
mchung
parents: 2
diff changeset
    97
            Utils.log.warning("Error on output: "+ee, ee);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
            //if (verbose > 0)  ee.printStackTrace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
            // Write partial output only if we are verbose.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
            if (verbose > 0)  finalOut.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
            if (ee instanceof IOException)  throw (IOException)ee;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
            if (ee instanceof RuntimeException)  throw (RuntimeException)ee;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
            throw new Error("error packing", ee);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   107
    Set<Entry>                       requiredEntries;  // for the CP
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   108
    Map<Attribute.Layout, int[]>     backCountTable;   // for layout callables
21278
ef8a3a2a72f2 8022746: List of spelling errors in API doc
malenkov
parents: 16050
diff changeset
   109
    int[][]     attrCounts;       // count attr. occurrences
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    void setup() {
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   112
        requiredEntries = new HashSet<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        setArchiveOptions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        trimClassAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        collectAttributeLayouts();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        pkg.buildGlobalConstantPool(requiredEntries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
        setBandIndexes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        makeNewAttributeBands();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        collectInnerClasses();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   122
    /*
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   123
     * Convenience function to choose an archive version based
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   124
     * on the class file versions observed within the archive
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   125
     * or set the user defined version preset via properties.
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   126
     */
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   127
    void chooseDefaultPackageVersion() throws IOException {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   128
        if (pkg.packageVersion != null) {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   129
            packageVersion = pkg.packageVersion;
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   130
            if (verbose > 0) {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   131
                Utils.log.info("package version overridden with: "
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   132
                                + packageVersion);
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   133
            }
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   134
            return;
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   135
        }
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   136
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   137
        Package.Version highV = getHighestClassVersion();
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   138
        // set the package version now
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   139
        if (highV.lessThan(JAVA6_MAX_CLASS_VERSION)) {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   140
            // There are only old classfiles in this segment or resources
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   141
            packageVersion = JAVA5_PACKAGE_VERSION;
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   142
        } else if (highV.equals(JAVA6_MAX_CLASS_VERSION) ||
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   143
                (highV.equals(JAVA7_MAX_CLASS_VERSION) && !pkg.cp.haveExtraTags())) {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   144
            // force down the package version if we have jdk7 classes without
15261
c5b882836677 8005252: pack200 should support MethodParameters
ksrini
parents: 13795
diff changeset
   145
            // any Indy references, this is because jdk7 class file (51.0) without
c5b882836677 8005252: pack200 should support MethodParameters
ksrini
parents: 13795
diff changeset
   146
            // Indy is identical to jdk6 class file (50.0).
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   147
            packageVersion = JAVA6_PACKAGE_VERSION;
15261
c5b882836677 8005252: pack200 should support MethodParameters
ksrini
parents: 13795
diff changeset
   148
        } else if (highV.equals(JAVA7_MAX_CLASS_VERSION)) {
c5b882836677 8005252: pack200 should support MethodParameters
ksrini
parents: 13795
diff changeset
   149
            packageVersion = JAVA7_PACKAGE_VERSION;
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   150
        } else {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   151
            // Normal case.  Use the newest archive format, when available
15261
c5b882836677 8005252: pack200 should support MethodParameters
ksrini
parents: 13795
diff changeset
   152
            packageVersion = JAVA8_PACKAGE_VERSION;
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   153
        }
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   154
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   155
        if (verbose > 0) {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   156
            Utils.log.info("Highest version class file: " + highV
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   157
                    + " package version: " + packageVersion);
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   158
        }
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   159
    }
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   160
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   161
    void checkVersion() throws IOException {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   162
        assert(packageVersion != null);
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   163
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   164
        if (packageVersion.lessThan(JAVA7_PACKAGE_VERSION)) {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   165
            // this bit was reserved for future use in previous versions
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   166
            if (testBit(archiveOptions, AO_HAVE_CP_EXTRAS)) {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   167
                throw new IOException("Format bits for Java 7 must be zero in previous releases");
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   168
            }
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   169
        }
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   170
        if (testBit(archiveOptions, AO_UNUSED_MBZ)) {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   171
            throw new IOException("High archive option bits are reserved and must be zero: " + Integer.toHexString(archiveOptions));
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   172
        }
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   173
    }
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   174
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    void setArchiveOptions() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        // Decide on some archive options early.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        // Does not decide on: AO_HAVE_SPECIAL_FORMATS,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        // AO_HAVE_CP_NUMBERS, AO_HAVE_FILE_HEADERS.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        // Also, AO_HAVE_FILE_OPTIONS may be forced on later.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        int minModtime = pkg.default_modtime;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        int maxModtime = pkg.default_modtime;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        int minOptions = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        int maxOptions = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        // Import defaults from package (deflate hint, etc.).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        archiveOptions |= pkg.default_options;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   188
        for (File file : pkg.files) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            int modtime = file.modtime;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            int options = file.options;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            if (minModtime == NO_MODTIME) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
                minModtime = maxModtime = modtime;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                if (minModtime > modtime)  minModtime = modtime;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                if (maxModtime < modtime)  maxModtime = modtime;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            minOptions &= options;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
            maxOptions |= options;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        if (pkg.default_modtime == NO_MODTIME) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            // Make everything else be a positive offset from here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            pkg.default_modtime = minModtime;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        if (minModtime != NO_MODTIME && minModtime != maxModtime) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            // Put them into a band.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            archiveOptions |= AO_HAVE_FILE_MODTIME;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        // If the archive deflation is set do not bother with each file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        if (!testBit(archiveOptions,AO_DEFLATE_HINT) && minOptions != -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            if (testBit(minOptions, FO_DEFLATE_HINT)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                // Every file has the deflate_hint set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                // Set it for the whole archive, and omit options.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                archiveOptions |= AO_DEFLATE_HINT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                minOptions -= FO_DEFLATE_HINT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                maxOptions -= FO_DEFLATE_HINT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            pkg.default_options |= minOptions;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            if (minOptions != maxOptions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                || minOptions != pkg.default_options) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                archiveOptions |= AO_HAVE_FILE_OPTIONS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        // Decide on default version number (majority rule).
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   225
        Map<Package.Version, int[]> verCounts = new HashMap<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        int bestCount = 0;
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   227
        Package.Version bestVersion = null;
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   228
        for (Class cls : pkg.classes) {
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   229
            Package.Version version = cls.getVersion();
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   230
            int[] var = verCounts.get(version);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            if (var == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
                var = new int[1];
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   233
                verCounts.put(version, var);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
            int count = (var[0] += 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
            //System.out.println("version="+version+" count="+count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
            if (bestCount < count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
                bestCount = count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                bestVersion = version;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        verCounts.clear();
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   243
        if (bestVersion == null)  bestVersion = JAVA_MIN_CLASS_VERSION;  // degenerate case
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   244
        pkg.defaultClassVersion = bestVersion;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        if (verbose > 0)
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   246
           Utils.log.info("Consensus version number in segment is " + bestVersion);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        if (verbose > 0)
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   248
            Utils.log.info("Highest version number in segment is "
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   249
                            + pkg.getHighestClassVersion());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        // Now add explicit pseudo-attrs. to classes with odd versions.
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   252
        for (Class cls : pkg.classes) {
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   253
            if (!cls.getVersion().equals(bestVersion)) {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   254
                Attribute a = makeClassFileVersionAttr(cls.getVersion());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
                if (verbose > 1) {
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   256
                    Utils.log.fine("Version "+cls.getVersion() + " of " + cls
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   257
                                     + " doesn't match package version "
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   258
                                     + bestVersion);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                // Note:  Does not add in "natural" order.  (Who cares?)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                cls.addAttribute(a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        // Decide if we are transmitting a huge resource file:
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   266
        for (File file : pkg.files) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            long len = file.getFileLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            if (len != (int)len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                archiveOptions |= AO_HAVE_FILE_SIZE_HI;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                if (verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                   Utils.log.info("Note: Huge resource file "+file.getFileName()+" forces 64-bit sizing");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        // Decide if code attributes typically have sub-attributes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        // In that case, to preserve compact 1-byte code headers,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        // we must declare unconditional presence of code flags.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        int cost0 = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        int cost1 = 0;
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   281
        for (Class cls : pkg.classes) {
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   282
            for (Class.Method m : cls.getMethods()) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                if (m.code != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                    if (m.code.attributeSize() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                        // cost of a useless unconditional flags byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                        cost1 += 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                    } else if (shortCodeHeader(m.code) != LONG_CODE_HEADER) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                        // cost of inflating a short header
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
                        cost0 += 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        if (cost0 > cost1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            archiveOptions |= AO_HAVE_ALL_CODE_FLAGS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        if (verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            Utils.log.info("archiveOptions = "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                             +"0b"+Integer.toBinaryString(archiveOptions));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    void writeFileHeader() throws IOException {
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   303
        chooseDefaultPackageVersion();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        writeArchiveMagic();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        writeArchiveHeader();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    // Local routine used to format fixed-format scalars
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    // in the file_header:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    private void putMagicInt32(int val) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        int res = val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        for (int i = 0; i < 4; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            archive_magic.putByte(0xFF & (res >>> 24));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            res <<= 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    void writeArchiveMagic() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        putMagicInt32(pkg.magic);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
    void writeArchiveHeader() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        // for debug only:  number of words optimized away
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   324
        int headerSizeForDebug = AH_LENGTH_MIN;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        // AO_HAVE_SPECIAL_FORMATS is set if non-default
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        // coding techniques are used, or if there are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        // compressor-defined attributes transmitted.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        boolean haveSpecial = testBit(archiveOptions, AO_HAVE_SPECIAL_FORMATS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
        if (!haveSpecial) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
            haveSpecial |= (band_headers.length() != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            haveSpecial |= (attrDefsWritten.length != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
            if (haveSpecial)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                archiveOptions |= AO_HAVE_SPECIAL_FORMATS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        }
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   336
        if (haveSpecial)
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   337
            headerSizeForDebug += AH_SPECIAL_FORMAT_LEN;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
        // AO_HAVE_FILE_HEADERS is set if there is any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
        // file or segment envelope information present.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        boolean haveFiles = testBit(archiveOptions, AO_HAVE_FILE_HEADERS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        if (!haveFiles) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            haveFiles |= (archiveNextCount > 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            haveFiles |= (pkg.default_modtime != NO_MODTIME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
            if (haveFiles)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                archiveOptions |= AO_HAVE_FILE_HEADERS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        }
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   348
        if (haveFiles)
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   349
            headerSizeForDebug += AH_FILE_HEADER_LEN;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        // AO_HAVE_CP_NUMBERS is set if there are any numbers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
        // in the global constant pool.  (Numbers are in 15% of classes.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        boolean haveNumbers = testBit(archiveOptions, AO_HAVE_CP_NUMBERS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        if (!haveNumbers) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            haveNumbers |= pkg.cp.haveNumbers();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            if (haveNumbers)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                archiveOptions |= AO_HAVE_CP_NUMBERS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        }
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   359
        if (haveNumbers)
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   360
            headerSizeForDebug += AH_CP_NUMBER_LEN;
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   361
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   362
        // AO_HAVE_CP_EXTRAS is set if there are constant pool entries
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   363
        // beyond the Java 6 version of the class file format.
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   364
        boolean haveCPExtra = testBit(archiveOptions, AO_HAVE_CP_EXTRAS);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   365
        if (!haveCPExtra) {
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   366
            haveCPExtra |= pkg.cp.haveExtraTags();
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   367
            if (haveCPExtra)
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   368
                archiveOptions |= AO_HAVE_CP_EXTRAS;
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   369
        }
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   370
        if (haveCPExtra)
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   371
            headerSizeForDebug += AH_CP_EXTRA_LEN;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   373
        // the archiveOptions are all initialized, sanity check now!.
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   374
        checkVersion();
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   375
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   376
        archive_header_0.putInt(packageVersion.minor);
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   377
        archive_header_0.putInt(packageVersion.major);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        if (verbose > 0)
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   379
            Utils.log.info("Package Version for this segment:" + packageVersion);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        archive_header_0.putInt(archiveOptions); // controls header format
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        assert(archive_header_0.length() == AH_LENGTH_0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        final int DUMMY = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
        if (haveFiles) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            assert(archive_header_S.length() == AH_ARCHIVE_SIZE_HI);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
            archive_header_S.putInt(DUMMY); // (archiveSize1 >>> 32)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
            assert(archive_header_S.length() == AH_ARCHIVE_SIZE_LO);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
            archive_header_S.putInt(DUMMY); // (archiveSize1 >>> 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
            assert(archive_header_S.length() == AH_LENGTH_S);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        // Done with unsized part of header....
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        if (haveFiles) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            archive_header_1.putInt(archiveNextCount);  // usually zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
            archive_header_1.putInt(pkg.default_modtime);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
            archive_header_1.putInt(pkg.files.size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        } else {
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   399
            assert(pkg.files.isEmpty());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        if (haveSpecial) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            archive_header_1.putInt(band_headers.length());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
            archive_header_1.putInt(attrDefsWritten.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
            assert(band_headers.length() == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
            assert(attrDefsWritten.length == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   410
        writeConstantPoolCounts(haveNumbers, haveCPExtra);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        archive_header_1.putInt(pkg.getAllInnerClasses().size());
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   413
        archive_header_1.putInt(pkg.defaultClassVersion.minor);
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   414
        archive_header_1.putInt(pkg.defaultClassVersion.major);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        archive_header_1.putInt(pkg.classes.size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   417
        // Sanity:  Make sure we came out to 29 (less optional fields):
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        assert(archive_header_0.length() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
               archive_header_S.length() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
               archive_header_1.length()
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   421
               == headerSizeForDebug);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        // Figure out all the sizes now, first cut:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        archiveSize0 = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        archiveSize1 = all_bands.outputSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        // Second cut:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        archiveSize0 += archive_magic.outputSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        archiveSize0 += archive_header_0.outputSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        archiveSize0 += archive_header_S.outputSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        // Make the adjustments:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        archiveSize1 -= archiveSize0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        // Patch the header:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        if (haveFiles) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            int archiveSizeHi = (int)(archiveSize1 >>> 32);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            int archiveSizeLo = (int)(archiveSize1 >>> 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            archive_header_S.patchValue(AH_ARCHIVE_SIZE_HI, archiveSizeHi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            archive_header_S.patchValue(AH_ARCHIVE_SIZE_LO, archiveSizeLo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
            int zeroLen = UNSIGNED5.getLength(DUMMY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            archiveSize0 += UNSIGNED5.getLength(archiveSizeHi) - zeroLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
            archiveSize0 += UNSIGNED5.getLength(archiveSizeLo) - zeroLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        if (verbose > 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            Utils.log.fine("archive sizes: "+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                             archiveSize0+"+"+archiveSize1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        assert(all_bands.outputSize() == archiveSize0+archiveSize1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   449
    void writeConstantPoolCounts(boolean haveNumbers, boolean haveCPExtra) throws IOException {
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   450
        for (byte tag : ConstantPool.TAGS_IN_ORDER) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            int count = pkg.cp.getIndexByTag(tag).size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
            switch (tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
            case CONSTANT_Utf8:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                // The null string is always first.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                if (count > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
                    assert(pkg.cp.getIndexByTag(tag).get(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                           == ConstantPool.getUtf8Entry(""));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            case CONSTANT_Integer:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            case CONSTANT_Float:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
            case CONSTANT_Long:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
            case CONSTANT_Double:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
                // Omit counts for numbers if possible.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                if (!haveNumbers) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                    assert(count == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                break;
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   470
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   471
            case CONSTANT_MethodHandle:
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   472
            case CONSTANT_MethodType:
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   473
            case CONSTANT_InvokeDynamic:
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   474
            case CONSTANT_BootstrapMethod:
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   475
                // Omit counts for newer entities if possible.
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   476
                if (!haveCPExtra) {
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   477
                    assert(count == 0);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   478
                    continue;
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   479
                }
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   480
                break;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
            archive_header_1.putInt(count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
    protected Index getCPIndex(byte tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        return pkg.cp.getIndexByTag(tag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
// (The following observations are out of date; they apply only to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
// "banding" the constant pool itself.  Later revisions of this algorithm
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
// applied the banding technique to every part of the package file,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
// applying the benefits more broadly.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
// Note:  Keeping the data separate in passes (or "bands") allows the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
// compressor to issue significantly shorter indexes for repeated data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
// The difference in zipped size is 4%, which is remarkable since the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
// unzipped sizes are the same (only the byte order differs).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
// After moving similar data into bands, it becomes natural to delta-encode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
// each band.  (This is especially useful if we sort the constant pool first.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
// Delta encoding saves an extra 5% in the output size (13% of the CP itself).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
// Because a typical delta usees much less data than a byte, the savings after
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
// zipping is even better:  A zipped delta-encoded package is 8% smaller than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
// a zipped non-delta-encoded package.  Thus, in the zipped file, a banded,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
// delta-encoded constant pool saves over 11% (of the total file size) compared
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
// with a zipped unbanded file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
    void writeConstantPool() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        IndexGroup cp = pkg.cp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        if (verbose > 0)  Utils.log.info("Writing CP");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   514
        for (byte tag : ConstantPool.TAGS_IN_ORDER) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
            Index index = cp.getIndexByTag(tag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            Entry[] cpMap = index.cpMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            if (verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
                Utils.log.info("Writing "+cpMap.length+" "+ConstantPool.tagName(tag)+" entries...");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
            if (optDumpBands) {
8803
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
   522
                try (PrintStream ps = new PrintStream(getDumpStream(index, ".idx"))) {
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
   523
                    printArrayTo(ps, cpMap, 0, cpMap.length);
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
   524
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
            switch (tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            case CONSTANT_Utf8:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
                writeUtf8Bands(cpMap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            case CONSTANT_Integer:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
                for (int i = 0; i < cpMap.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
                    NumberEntry e = (NumberEntry) cpMap[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                    int x = ((Integer)e.numberValue()).intValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                    cp_Int.putInt(x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            case CONSTANT_Float:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                for (int i = 0; i < cpMap.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                    NumberEntry e = (NumberEntry) cpMap[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                    float fx = ((Float)e.numberValue()).floatValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                    int x = Float.floatToIntBits(fx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                    cp_Float.putInt(x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            case CONSTANT_Long:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                for (int i = 0; i < cpMap.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                    NumberEntry e = (NumberEntry) cpMap[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
                    long x = ((Long)e.numberValue()).longValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                    cp_Long_hi.putInt((int)(x >>> 32));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                    cp_Long_lo.putInt((int)(x >>> 0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            case CONSTANT_Double:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                for (int i = 0; i < cpMap.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                    NumberEntry e = (NumberEntry) cpMap[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                    double dx = ((Double)e.numberValue()).doubleValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
                    long x = Double.doubleToLongBits(dx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
                    cp_Double_hi.putInt((int)(x >>> 32));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
                    cp_Double_lo.putInt((int)(x >>> 0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            case CONSTANT_String:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                for (int i = 0; i < cpMap.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                    StringEntry e = (StringEntry) cpMap[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                    cp_String.putRef(e.ref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
            case CONSTANT_Class:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
                for (int i = 0; i < cpMap.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
                    ClassEntry e = (ClassEntry) cpMap[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                    cp_Class.putRef(e.ref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
            case CONSTANT_Signature:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                writeSignatureBands(cpMap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
            case CONSTANT_NameandType:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
                for (int i = 0; i < cpMap.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
                    DescriptorEntry e = (DescriptorEntry) cpMap[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
                    cp_Descr_name.putRef(e.nameRef);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                    cp_Descr_type.putRef(e.typeRef);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            case CONSTANT_Fieldref:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                writeMemberRefs(tag, cpMap, cp_Field_class, cp_Field_desc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            case CONSTANT_Methodref:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
                writeMemberRefs(tag, cpMap, cp_Method_class, cp_Method_desc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            case CONSTANT_InterfaceMethodref:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
                writeMemberRefs(tag, cpMap, cp_Imethod_class, cp_Imethod_desc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                break;
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   594
            case CONSTANT_MethodHandle:
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   595
                for (int i = 0; i < cpMap.length; i++) {
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   596
                    MethodHandleEntry e = (MethodHandleEntry) cpMap[i];
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   597
                    cp_MethodHandle_refkind.putInt(e.refKind);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   598
                    cp_MethodHandle_member.putRef(e.memRef);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   599
                }
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   600
                break;
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   601
            case CONSTANT_MethodType:
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   602
                for (int i = 0; i < cpMap.length; i++) {
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   603
                    MethodTypeEntry e = (MethodTypeEntry) cpMap[i];
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   604
                    cp_MethodType.putRef(e.typeRef);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   605
                }
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   606
                break;
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   607
            case CONSTANT_InvokeDynamic:
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   608
                for (int i = 0; i < cpMap.length; i++) {
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   609
                    InvokeDynamicEntry e = (InvokeDynamicEntry) cpMap[i];
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   610
                    cp_InvokeDynamic_spec.putRef(e.bssRef);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   611
                    cp_InvokeDynamic_desc.putRef(e.descRef);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   612
                }
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   613
                break;
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   614
            case CONSTANT_BootstrapMethod:
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   615
                for (int i = 0; i < cpMap.length; i++) {
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   616
                    BootstrapMethodEntry e = (BootstrapMethodEntry) cpMap[i];
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   617
                    cp_BootstrapMethod_ref.putRef(e.bsmRef);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   618
                    cp_BootstrapMethod_arg_count.putInt(e.argRefs.length);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   619
                    for (Entry argRef : e.argRefs) {
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   620
                        cp_BootstrapMethod_arg.putRef(argRef);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   621
                    }
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   622
                }
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   623
                break;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
            default:
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   625
                throw new AssertionError("unexpected CP tag in package");
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   626
            }
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   627
        }
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   628
        if (optDumpBands || verbose > 1) {
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   629
            for (byte tag = CONSTANT_GroupFirst; tag < CONSTANT_GroupLimit; tag++) {
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   630
                Index index = cp.getIndexByTag(tag);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   631
                if (index == null || index.isEmpty())  continue;
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   632
                Entry[] cpMap = index.cpMap;
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   633
                if (verbose > 1)
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   634
                    Utils.log.info("Index group "+ConstantPool.tagName(tag)+" contains "+cpMap.length+" entries.");
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   635
                if (optDumpBands) {
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   636
                    try (PrintStream ps = new PrintStream(getDumpStream(index.debugName, tag, ".gidx", index))) {
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   637
                        printArrayTo(ps, cpMap, 0, cpMap.length, true);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   638
                    }
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
   639
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
    void writeUtf8Bands(Entry[] cpMap) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
        if (cpMap.length == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
            return;  // nothing to write
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
        // The first element must always be the empty string.
52902
e3398b2e1ab0 8214971: Replace use of string.equals("") with isEmpty()
rriggs
parents: 47216
diff changeset
   649
        assert(cpMap[0].stringValue().isEmpty());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        final int SUFFIX_SKIP_1 = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
        final int PREFIX_SKIP_2 = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
        // Fetch the char arrays, first of all.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
        char[][] chars = new char[cpMap.length][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
        for (int i = 0; i < chars.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
            chars[i] = cpMap[i].stringValue().toCharArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        // First band:  Write lengths of shared prefixes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        int[] prefixes = new int[cpMap.length];  // includes 2 skipped zeroes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
        char[] prevChars = {};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        for (int i = 0; i < chars.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
            int prefix = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
            char[] curChars = chars[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
            int limit = Math.min(curChars.length, prevChars.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
            while (prefix < limit && curChars[prefix] == prevChars[prefix])
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                prefix++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
            prefixes[i] = prefix;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
            if (i >= PREFIX_SKIP_2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
                cp_Utf8_prefix.putInt(prefix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
                assert(prefix == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
            prevChars = curChars;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        // Second band:  Write lengths of unshared suffixes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
        // Third band:  Write the char values in the unshared suffixes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        for (int i = 0; i < chars.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
            char[] str = chars[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
            int prefix = prefixes[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
            int suffix = str.length - prefixes[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
            boolean isPacked = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            if (suffix == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
                // Zero suffix length is special flag to indicate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
                // separate treatment in cp_Utf8_big bands.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
                // This suffix length never occurs naturally,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
                // except in the one case of a zero-length string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
                // (If it occurs, it is the first, due to sorting.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
                // The zero length string must, paradoxically, be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
                // encoded as a zero-length cp_Utf8_big band.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
                // This wastes exactly (& tolerably) one null byte.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
                isPacked = (i >= SUFFIX_SKIP_1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
                // Do not bother to add an empty "(Utf8_big_0)" band.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
                // Also, the initial empty string does not require a band.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
            } else if (optBigStrings && effort > 1 && suffix > 100) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
                int numWide = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
                for (int n = 0; n < suffix; n++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
                    if (str[prefix+n] > 127) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
                        numWide++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
                if (numWide > 100) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
                    // Try packing the chars with an alternate encoding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
                    isPacked = tryAlternateEncoding(i, numWide, str, prefix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
            if (i < SUFFIX_SKIP_1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
                // No output.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
                assert(!isPacked);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
                assert(suffix == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
            } else if (isPacked) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
                // Mark packed string with zero-length suffix count.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
                // This tells the unpacker to go elsewhere for the suffix bits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
                // Fourth band:  Write unshared suffix with alternate coding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
                cp_Utf8_suffix.putInt(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
                cp_Utf8_big_suffix.putInt(suffix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
                assert(suffix != 0);  // would be ambiguous
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
                // Normal string.  Save suffix in third and fourth bands.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                cp_Utf8_suffix.putInt(suffix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
                for (int n = 0; n < suffix; n++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
                    int ch = str[prefix+n];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                    cp_Utf8_chars.putInt(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        if (verbose > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
            int normCharCount = cp_Utf8_chars.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            int packCharCount = cp_Utf8_big_chars.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
            int charCount = normCharCount + packCharCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
            Utils.log.info("Utf8string #CHARS="+charCount+" #PACKEDCHARS="+packCharCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
    private boolean tryAlternateEncoding(int i, int numWide,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
                                         char[] str, int prefix) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        int suffix = str.length - prefix;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        int[] cvals = new int[suffix];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        for (int n = 0; n < suffix; n++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
            cvals[n] = str[prefix+n];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        CodingChooser cc = getCodingChooser();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
        Coding bigRegular = cp_Utf8_big_chars.regularCoding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
        String bandName = "(Utf8_big_"+i+")";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
        int[] sizes = { 0, 0 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
        final int BYTE_SIZE = CodingChooser.BYTE_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        final int ZIP_SIZE = CodingChooser.ZIP_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
        if (verbose > 1 || cc.verbose > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
            Utils.log.fine("--- chooseCoding "+bandName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        CodingMethod special = cc.choose(cvals, bigRegular, sizes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
        Coding charRegular = cp_Utf8_chars.regularCoding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
        if (verbose > 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
            Utils.log.fine("big string["+i+"] len="+suffix+" #wide="+numWide+" size="+sizes[BYTE_SIZE]+"/z="+sizes[ZIP_SIZE]+" coding "+special);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        if (special != charRegular) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
            int specialZipSize = sizes[ZIP_SIZE];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
            int[] normalSizes = cc.computeSize(charRegular, cvals);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
            int normalZipSize = normalSizes[ZIP_SIZE];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
            int minWin = Math.max(5, normalZipSize/1000);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
            if (verbose > 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                Utils.log.fine("big string["+i+"] normalSize="+normalSizes[BYTE_SIZE]+"/z="+normalSizes[ZIP_SIZE]+" win="+(specialZipSize<normalZipSize-minWin));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
            if (specialZipSize < normalZipSize-minWin) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                IntBand big = cp_Utf8_big_chars.newIntBand(bandName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
                big.initializeValues(cvals);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
    void writeSignatureBands(Entry[] cpMap) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        for (int i = 0; i < cpMap.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            SignatureEntry e = (SignatureEntry) cpMap[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
            cp_Signature_form.putRef(e.formRef);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
            for (int j = 0; j < e.classRefs.length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
                cp_Signature_classes.putRef(e.classRefs[j]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
    void writeMemberRefs(byte tag, Entry[] cpMap, CPRefBand cp_class, CPRefBand cp_desc) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
        for (int i = 0; i < cpMap.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            MemberEntry e = (MemberEntry) cpMap[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
            cp_class.putRef(e.classRef);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
            cp_desc.putRef(e.descRef);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
    void writeFiles() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
        int numFiles = pkg.files.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
        if (numFiles == 0)  return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
        int options = archiveOptions;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
        boolean haveSizeHi  = testBit(options, AO_HAVE_FILE_SIZE_HI);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        boolean haveModtime = testBit(options, AO_HAVE_FILE_MODTIME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        boolean haveOptions = testBit(options, AO_HAVE_FILE_OPTIONS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
        if (!haveOptions) {
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   797
            for (File file : pkg.files) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
                if (file.isClassStub()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
                    haveOptions = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
                    options |= AO_HAVE_FILE_OPTIONS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
                    archiveOptions = options;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
        if (haveSizeHi || haveModtime || haveOptions || !pkg.files.isEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
            options |= AO_HAVE_FILE_HEADERS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
            archiveOptions = options;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
        }
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   810
        for (File file : pkg.files) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
            file_name.putRef(file.name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
            long len = file.getFileLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
            file_size_lo.putInt((int)len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
            if (haveSizeHi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
                file_size_hi.putInt((int)(len >>> 32));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
            if (haveModtime)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
                file_modtime.putInt(file.modtime - pkg.default_modtime);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
            if (haveOptions)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
                file_options.putInt(file.options);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
            file.writeTo(file_bits.collectorStream());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
            if (verbose > 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
                Utils.log.fine("Wrote "+len+" bytes of "+file.name.stringValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
        if (verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
            Utils.log.info("Wrote "+numFiles+" resource files");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
    void collectAttributeLayouts() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
        maxFlags = new int[ATTR_CONTEXT_LIMIT];
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   830
        allLayouts = new FixedList<>(ATTR_CONTEXT_LIMIT);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
        for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
29986
97167d851fc4 8078467: Update core libraries to use diamond with anonymous classes
darcy
parents: 25859
diff changeset
   832
            allLayouts.set(i, new HashMap<>());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        // Collect maxFlags and allLayouts.
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   835
        for (Class cls : pkg.classes) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
            visitAttributeLayoutsIn(ATTR_CONTEXT_CLASS, cls);
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   837
            for (Class.Field f : cls.getFields()) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
                visitAttributeLayoutsIn(ATTR_CONTEXT_FIELD, f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
            }
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   840
            for (Class.Method m : cls.getMethods()) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                visitAttributeLayoutsIn(ATTR_CONTEXT_METHOD, m);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                if (m.code != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                    visitAttributeLayoutsIn(ATTR_CONTEXT_CODE, m.code);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
        // If there are many species of attributes, use 63-bit flags.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
        for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   849
            int nl = allLayouts.get(i).size();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
            boolean haveLongFlags = haveFlagsHi(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
            final int TOO_MANY_ATTRS = 32 /*int flag size*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
                - 12 /*typical flag bits in use*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
                + 4  /*typical number of OK overflows*/;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
            if (nl >= TOO_MANY_ATTRS) {  // heuristic
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
                int mask = 1<<(LG_AO_HAVE_XXX_FLAGS_HI+i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
                archiveOptions |= mask;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
                haveLongFlags = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                if (verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                   Utils.log.info("Note: Many "+Attribute.contextName(i)+" attributes forces 63-bit flags");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
            if (verbose > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                Utils.log.fine(Attribute.contextName(i)+".maxFlags = 0x"+Integer.toHexString(maxFlags[i]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                Utils.log.fine(Attribute.contextName(i)+".#layouts = "+nl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
            assert(haveFlagsHi(i) == haveLongFlags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
        initAttrIndexLimit();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
        // Standard indexes can never conflict with flag bits.  Assert it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
            assert((attrFlagMask[i] & maxFlags[i]) == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
        // Collect counts for both predefs. and custom defs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
        // Decide on custom, local attribute definitions.
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   875
        backCountTable = new HashMap<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
        attrCounts = new int[ATTR_CONTEXT_LIMIT][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
        for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
            // Now the remaining defs in allLayouts[i] need attr. indexes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
            // Fill up unused flag bits with new defs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
            // Unused bits are those which are not used by predefined attrs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
            // and which are always clear in the classfiles.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
            long avHiBits = ~(maxFlags[i] | attrFlagMask[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
            assert(attrIndexLimit[i] > 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
            assert(attrIndexLimit[i] < 64);  // all bits fit into a Java long
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
            avHiBits &= (1L<<attrIndexLimit[i])-1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
            int nextLoBit = 0;
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   887
            Map<Attribute.Layout, int[]> defMap = allLayouts.get(i);
13795
73850c397272 7193406: Clean-up JDK Build Warnings in java.util, java.io
dxu
parents: 12857
diff changeset
   888
            @SuppressWarnings({"unchecked", "rawtypes"})
10115
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
   889
            Map.Entry<Attribute.Layout, int[]>[] layoutsAndCounts =
10135
8186b3499405 7069870: Parts of the JDK erroneously rely on generic array initializers with diamond
jjg
parents: 10115
diff changeset
   890
                    new Map.Entry[defMap.size()];
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   891
            defMap.entrySet().toArray(layoutsAndCounts);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
            // Sort by count, most frequent first.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
            // Predefs. participate in this sort, though it does not matter.
10115
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
   894
            Arrays.sort(layoutsAndCounts,
29986
97167d851fc4 8078467: Update core libraries to use diamond with anonymous classes
darcy
parents: 25859
diff changeset
   895
                        new Comparator<>() {
10115
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
   896
                public int compare(Map.Entry<Attribute.Layout, int[]> e0,
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
   897
                                   Map.Entry<Attribute.Layout, int[]> e1) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
                    // Primary sort key is count, reversed.
10115
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
   899
                    int r = -(e0.getValue()[0] - e1.getValue()[0]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
                    if (r != 0)  return r;
10115
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
   901
                    return e0.getKey().compareTo(e1.getKey());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
            });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
            attrCounts[i] = new int[attrIndexLimit[i]+layoutsAndCounts.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
            for (int j = 0; j < layoutsAndCounts.length; j++) {
10115
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
   906
                Map.Entry<Attribute.Layout, int[]> e = layoutsAndCounts[j];
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
   907
                Attribute.Layout def = e.getKey();
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
   908
                int count = e.getValue()[0];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
                int index;
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   910
                Integer predefIndex = attrIndexTable.get(def);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
                if (predefIndex != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
                    // The index is already set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
                    index = predefIndex.intValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
                } else if (avHiBits != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
                    while ((avHiBits & 1) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
                        avHiBits >>>= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
                        nextLoBit += 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
                    avHiBits -= 1;  // clear low bit; we are using it now
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
                    // Update attrIndexTable:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
                    index = setAttributeLayoutIndex(def, nextLoBit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
                    // Update attrIndexTable:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
                    index = setAttributeLayoutIndex(def, ATTR_INDEX_OVERFLOW);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
                // Now that we know the index, record the count of this def.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
                attrCounts[i][index] = count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
                // For all callables in the def, keep a tally of back-calls.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
                Attribute.Layout.Element[] cbles = def.getCallables();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
                final int[] bc = new int[cbles.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
                for (int k = 0; k < cbles.length; k++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
                    assert(cbles[k].kind == Attribute.EK_CBLE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
                    if (!cbles[k].flagTest(Attribute.EF_BACK)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
                        bc[k] = -1;  // no count to accumulate here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
                backCountTable.put(def, bc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
                if (predefIndex == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
                    // Make sure the package CP can name the local attribute.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
                    Entry ne = ConstantPool.getUtf8Entry(def.name());
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
   944
                    String layout = def.layoutForClassVersion(getHighestClassVersion());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
                    Entry le = ConstantPool.getUtf8Entry(layout);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
                    requiredEntries.add(ne);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
                    requiredEntries.add(le);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
                    if (verbose > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
                        if (index < attrIndexLimit[i])
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
                           Utils.log.info("Using free flag bit 1<<"+index+" for "+count+" occurrences of "+def);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
                        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
                            Utils.log.info("Using overflow index "+index+" for "+count+" occurrences of "+def);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
        // Later, when emitting attr_definition_bands, we will look at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
        // attrDefSeen and attrDefs at position 32/63 and beyond.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
        // The attrIndexTable will provide elements of xxx_attr_indexes bands.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
        // Done with scratch variables:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
        maxFlags = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
        allLayouts = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
    // Scratch variables for processing attributes and flags.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
    int[] maxFlags;
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   968
    List<Map<Attribute.Layout, int[]>> allLayouts;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
    void visitAttributeLayoutsIn(int ctype, Attribute.Holder h) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
        // Make note of which flags appear in the class file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
        // Set them in maxFlags.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
        maxFlags[ctype] |= h.flags;
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   974
        for (Attribute a : h.getAttributes()) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
            Attribute.Layout def = a.layout();
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   976
            Map<Attribute.Layout, int[]> defMap = allLayouts.get(ctype);
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   977
            int[] count = defMap.get(def);
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   978
            if (count == null) {
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   979
                defMap.put(def, count = new int[1]);
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   980
            }
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   981
            if (count[0] < Integer.MAX_VALUE) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
                count[0] += 1;
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   983
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
    Attribute.Layout[] attrDefsWritten;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
    void writeAttrDefs() throws IOException {
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   990
        List<Object[]> defList = new ArrayList<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
        for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   992
            int limit = attrDefs.get(i).size();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
            for (int j = 0; j < limit; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
                int header = i;  // ctype
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
                if (j < attrIndexLimit[i]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
                    header |= ((j + ADH_BIT_IS_LSB) << ADH_BIT_SHIFT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
                    assert(header < 0x100);  // must fit into a byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
                    // (...else header is simply ctype, with zero high bits.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
                    if (!testBit(attrDefSeen[i], 1L<<j)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
                        // either undefined or predefined; nothing to write
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
                        continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
                }
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1004
                Attribute.Layout def = attrDefs.get(i).get(j);
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1005
                defList.add(new Object[]{ Integer.valueOf(header), def });
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1006
                assert(Integer.valueOf(j).equals(attrIndexTable.get(def)));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
        // Sort the new attr defs into some "natural" order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
        int numAttrDefs = defList.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
        Object[][] defs = new Object[numAttrDefs][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
        defList.toArray(defs);
29986
97167d851fc4 8078467: Update core libraries to use diamond with anonymous classes
darcy
parents: 25859
diff changeset
  1013
        Arrays.sort(defs, new Comparator<>() {
10115
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
  1014
            public int compare(Object[] a0, Object[] a1) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
                // Primary sort key is attr def header.
10115
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
  1016
                @SuppressWarnings("unchecked")
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
                int r = ((Comparable)a0[0]).compareTo(a1[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
                if (r != 0)  return r;
10115
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
  1019
                Integer ind0 = attrIndexTable.get(a0[1]);
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
  1020
                Integer ind1 = attrIndexTable.get(a1[1]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
                // Secondary sort key is attribute index.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
                // (This must be so, in order to keep overflow attr order.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
                assert(ind0 != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
                assert(ind1 != null);
10115
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 8803
diff changeset
  1025
                return ind0.compareTo(ind1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
        });
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
        attrDefsWritten = new Attribute.Layout[numAttrDefs];
8803
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1029
        try (PrintStream dump = !optDumpBands ? null
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1030
                 : new PrintStream(getDumpStream(attr_definition_headers, ".def")))
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1031
        {
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1032
            int[] indexForDebug = Arrays.copyOf(attrIndexLimit, ATTR_CONTEXT_LIMIT);
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1033
            for (int i = 0; i < defs.length; i++) {
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1034
                int header = ((Integer)defs[i][0]).intValue();
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1035
                Attribute.Layout def = (Attribute.Layout) defs[i][1];
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1036
                attrDefsWritten[i] = def;
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1037
                assert((header & ADH_CONTEXT_MASK) == def.ctype());
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1038
                attr_definition_headers.putByte(header);
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1039
                attr_definition_name.putRef(ConstantPool.getUtf8Entry(def.name()));
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
  1040
                String layout = def.layoutForClassVersion(getHighestClassVersion());
8803
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1041
                attr_definition_layout.putRef(ConstantPool.getUtf8Entry(layout));
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1042
                // Check that we are transmitting that correct attribute index:
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1043
                boolean debug = false;
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1044
                assert(debug = true);
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1045
                if (debug) {
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1046
                    int hdrIndex = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1047
                    if (hdrIndex < 0)  hdrIndex = indexForDebug[def.ctype()]++;
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1048
                    int realIndex = (attrIndexTable.get(def)).intValue();
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1049
                    assert(hdrIndex == realIndex);
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1050
                }
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1051
                if (dump != null) {
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1052
                    int index = (header >> ADH_BIT_SHIFT) - ADH_BIT_IS_LSB;
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1053
                    dump.println(index+" "+def);
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 8570
diff changeset
  1054
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
    void writeAttrCounts() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
        // Write the four xxx_attr_calls bands.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
        for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
            MultiBand xxx_attr_bands = attrBands[ctype];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
            IntBand xxx_attr_calls = getAttrBand(xxx_attr_bands, AB_ATTR_CALLS);
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1064
            Attribute.Layout[] defs = new Attribute.Layout[attrDefs.get(ctype).size()];
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1065
            attrDefs.get(ctype).toArray(defs);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
            for (boolean predef = true; ; predef = false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
                for (int ai = 0; ai < defs.length; ai++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
                    Attribute.Layout def = defs[ai];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
                    if (def == null)  continue;  // unused index
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
                    if (predef != isPredefinedAttr(ctype, ai))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
                        continue;  // wrong pass
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
                    int totalCount = attrCounts[ctype][ai];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
                    if (totalCount == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
                        continue;  // irrelevant
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1075
                    int[] bc = backCountTable.get(def);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
                    for (int j = 0; j < bc.length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
                        if (bc[j] >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
                            int backCount = bc[j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
                            bc[j] = -1;  // close out; do not collect further counts
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
                            xxx_attr_calls.putInt(backCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
                            assert(def.getCallables()[j].flagTest(Attribute.EF_BACK));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
                            assert(!def.getCallables()[j].flagTest(Attribute.EF_BACK));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
                if (!predef)  break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
    void trimClassAttributes() {
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1093
        for (Class cls : pkg.classes) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
            // Replace "obvious" SourceFile attrs by null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
            cls.minimizeSourceFile();
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1096
            // BootstrapMethods should never have been inserted.
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1097
            assert(cls.getAttribute(Package.attrBootstrapMethodsEmpty) == null);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
    void collectInnerClasses() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
        // Capture inner classes, removing them from individual classes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
        // Irregular inner classes must stay local, though.
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1104
        Map<ClassEntry, InnerClass> allICMap = new HashMap<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
        // First, collect a consistent global set.
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1106
        for (Class cls : pkg.classes) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
            if (!cls.hasInnerClasses())  continue;
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1108
            for (InnerClass ic : cls.getInnerClasses()) {
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1109
                InnerClass pic = allICMap.put(ic.thisClass, ic);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
                if (pic != null && !pic.equals(ic) && pic.predictable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
                    // Different ICs.  Choose the better to make global.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
                    allICMap.put(pic.thisClass, pic);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
        InnerClass[] allICs = new InnerClass[allICMap.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
        allICMap.values().toArray(allICs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
        allICMap = null;  // done with it
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
        // Note: The InnerClasses attribute must be in a valid order,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
        // so that A$B always occurs earlier than A$B$C.  This is an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
        // important side-effect of sorting lexically by class name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
        Arrays.sort(allICs);  // put in canonical order
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
        pkg.setAllInnerClasses(Arrays.asList(allICs));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
        // Next, empty out of every local set the consistent entries.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
        // Calculate whether there is any remaining need to have a local
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
        // set, and whether it needs to be locked.
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1130
        for (Class cls : pkg.classes) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
            cls.minimizeLocalICs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
    void writeInnerClasses() throws IOException {
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1136
        for (InnerClass ic : pkg.getAllInnerClasses()) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
            int flags = ic.flags;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
            assert((flags & ACC_IC_LONG_FORM) == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
            if (!ic.predictable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
                flags |= ACC_IC_LONG_FORM;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
            ic_this_class.putRef(ic.thisClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
            ic_flags.putInt(flags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
            if (!ic.predictable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
                ic_outer_class.putRef(ic.outerClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
                ic_name.putRef(ic.name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
    /** If there are any extra InnerClasses entries to write which are
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
     *  not already implied by the global table, put them into a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
     *  local attribute.  This is expected to be rare.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
    void writeLocalInnerClasses(Class cls) throws IOException {
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1156
        List<InnerClass> localICs = cls.getInnerClasses();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
        class_InnerClasses_N.putInt(localICs.size());
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1158
        for(InnerClass ic : localICs) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
            class_InnerClasses_RC.putRef(ic.thisClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
            // Is it redundant with the global version?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
            if (ic.equals(pkg.getGlobalInnerClass(ic.thisClass))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
                // A zero flag means copy a global IC here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
                class_InnerClasses_F.putInt(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
                int flags = ic.flags;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
                if (flags == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
                    flags = ACC_IC_LONG_FORM;  // force it to be non-zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
                class_InnerClasses_F.putInt(flags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
                class_InnerClasses_outer_RCN.putRef(ic.outerClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
                class_InnerClasses_name_RUN.putRef(ic.name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
    void writeClassesAndByteCodes() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
        Class[] classes = new Class[pkg.classes.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
        pkg.classes.toArray(classes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
        // Note:  This code respects the order in which caller put classes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
        if (verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
            Utils.log.info("  ...scanning "+classes.length+" classes...");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
        int nwritten = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
        for (int i = 0; i < classes.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
            // Collect the class body, sans bytecodes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
            Class cls = classes[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
            if (verbose > 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
                Utils.log.fine("Scanning "+cls);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
            ClassEntry   thisClass  = cls.thisClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
            ClassEntry   superClass = cls.superClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
            ClassEntry[] interfaces = cls.interfaces;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
            // Encode rare case of null superClass as thisClass:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
            assert(superClass != thisClass);  // bad class file!?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
            if (superClass == null)  superClass = thisClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
            class_this.putRef(thisClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
            class_super.putRef(superClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
            class_interface_count.putInt(cls.interfaces.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
            for (int j = 0; j < interfaces.length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
                class_interface.putRef(interfaces[j]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
            writeMembers(cls);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
            writeAttrs(ATTR_CONTEXT_CLASS, cls, cls);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
            nwritten++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
            if (verbose > 0 && (nwritten % 1000) == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
                Utils.log.info("Have scanned "+nwritten+" classes...");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
    void writeMembers(Class cls) throws IOException {
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1212
        List<Class.Field> fields = cls.getFields();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
        class_field_count.putInt(fields.size());
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1214
        for (Class.Field f : fields) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
            field_descr.putRef(f.getDescriptor());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
            writeAttrs(ATTR_CONTEXT_FIELD, f, cls);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1219
        List<Class.Method> methods = cls.getMethods();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
        class_method_count.putInt(methods.size());
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1221
        for (Class.Method m : methods) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
            method_descr.putRef(m.getDescriptor());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
            writeAttrs(ATTR_CONTEXT_METHOD, m, cls);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
            assert((m.code != null) == (m.getAttribute(attrCodeEmpty) != null));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
            if (m.code != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
                writeCodeHeader(m.code);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
                writeByteCodes(m.code);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
    void writeCodeHeader(Code c) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
        boolean attrsOK = testBit(archiveOptions, AO_HAVE_ALL_CODE_FLAGS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
        int na = c.attributeSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
        int sc = shortCodeHeader(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
        if (!attrsOK && na > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
            // We must write flags, and can only do so for long headers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
            sc = LONG_CODE_HEADER;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
        if (verbose > 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
            int siglen = c.getMethod().getArgumentSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
            Utils.log.fine("Code sizes info "+c.max_stack+" "+c.max_locals+" "+c.getHandlerCount()+" "+siglen+" "+na+(sc > 0 ? " SHORT="+sc : ""));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
        code_headers.putByte(sc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
        if (sc == LONG_CODE_HEADER) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
            code_max_stack.putInt(c.getMaxStack());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
            code_max_na_locals.putInt(c.getMaxNALocals());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
            code_handler_count.putInt(c.getHandlerCount());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
            assert(attrsOK || na == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
            assert(c.getHandlerCount() < shortCodeHeader_h_limit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
        writeCodeHandlers(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
        if (sc == LONG_CODE_HEADER || attrsOK)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
            writeAttrs(ATTR_CONTEXT_CODE, c, c.thisClass());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
    void writeCodeHandlers(Code c) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
        int sum, del;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
        for (int j = 0, jmax = c.getHandlerCount(); j < jmax; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
            code_handler_class_RCN.putRef(c.handler_class[j]); // null OK
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
            // Encode end as offset from start, and catch as offset from end,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
            // because they are strongly correlated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
            sum = c.encodeBCI(c.handler_start[j]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
            code_handler_start_P.putInt(sum);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
            del = c.encodeBCI(c.handler_end[j]) - sum;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
            code_handler_end_PO.putInt(del);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
            sum += del;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
            del = c.encodeBCI(c.handler_catch[j]) - sum;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
            code_handler_catch_PO.putInt(del);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
    // Generic routines for writing attributes and flags of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
    // classes, fields, methods, and codes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
    void writeAttrs(int ctype,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
                    final Attribute.Holder h,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
                    Class cls) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
        MultiBand xxx_attr_bands = attrBands[ctype];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
        IntBand xxx_flags_hi = getAttrBand(xxx_attr_bands, AB_FLAGS_HI);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
        IntBand xxx_flags_lo = getAttrBand(xxx_attr_bands, AB_FLAGS_LO);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
        boolean haveLongFlags = haveFlagsHi(ctype);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
        assert(attrIndexLimit[ctype] == (haveLongFlags? 63: 32));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
        if (h.attributes == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
            xxx_flags_lo.putInt(h.flags);  // no extra bits to set here
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
            if (haveLongFlags)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
                xxx_flags_hi.putInt(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
        if (verbose > 3)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
            Utils.log.fine("Transmitting attrs for "+h+" flags="+Integer.toHexString(h.flags));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
        long flagMask = attrFlagMask[ctype];  // which flags are attr bits?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
        long flagsToAdd = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
        int overflowCount = 0;
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1295
        for (Attribute a : h.attributes) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
            Attribute.Layout def = a.layout();
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1297
            int index = (attrIndexTable.get(def)).intValue();
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1298
            assert(attrDefs.get(ctype).get(index) == def);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
            if (verbose > 3)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
                Utils.log.fine("add attr @"+index+" "+a+" in "+h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
            if (index < attrIndexLimit[ctype] && testBit(flagMask, 1L<<index)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
                if (verbose > 3)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
                    Utils.log.fine("Adding flag bit 1<<"+index+" in "+Long.toHexString(flagMask));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
                assert(!testBit(h.flags, 1L<<index));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
                flagsToAdd |= (1L<<index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
                flagMask -= (1L<<index);  // do not use this bit twice here
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
                // an overflow attr.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
                flagsToAdd |= (1L<<X_ATTR_OVERFLOW);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
                overflowCount += 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
                if (verbose > 3)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
                    Utils.log.fine("Adding overflow attr #"+overflowCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
                IntBand xxx_attr_indexes = getAttrBand(xxx_attr_bands, AB_ATTR_INDEXES);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
                xxx_attr_indexes.putInt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
                // System.out.println("overflow @"+index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
            if (def.bandCount == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
                if (def == attrInnerClassesEmpty) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
                    // Special logic to write this attr.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
                    writeLocalInnerClasses((Class) h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
                // Empty attr; nothing more to write here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
            assert(a.fixups == null);
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1327
            final Band[] ab = attrBandTable.get(def);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
            assert(ab != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
            assert(ab.length == def.bandCount);
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1330
            final int[] bc = backCountTable.get(def);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
            assert(bc != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
            assert(bc.length == def.getCallables().length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
            // Write one attribute of type def into ab.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
            if (verbose > 2)  Utils.log.fine("writing "+a+" in "+h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
            boolean isCV = (ctype == ATTR_CONTEXT_FIELD && def == attrConstantValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
            if (isCV)  setConstantValueIndex((Class.Field)h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
            a.parse(cls, a.bytes(), 0, a.size(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
                      new Attribute.ValueStream() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
                public void putInt(int bandIndex, int value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
                    ((IntBand) ab[bandIndex]).putInt(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
                public void putRef(int bandIndex, Entry ref) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
                    ((CPRefBand) ab[bandIndex]).putRef(ref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
                public int encodeBCI(int bci) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
                    Code code = (Code) h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
                    return code.encodeBCI(bci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
                public void noteBackCall(int whichCallable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
                    assert(bc[whichCallable] >= 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
                    bc[whichCallable] += 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
            });
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
            if (isCV)  setConstantValueIndex(null);  // clean up
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
        if (overflowCount > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
            IntBand xxx_attr_count = getAttrBand(xxx_attr_bands, AB_ATTR_COUNT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
            xxx_attr_count.putInt(overflowCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
        xxx_flags_lo.putInt(h.flags | (int)flagsToAdd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
        if (haveLongFlags)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
            xxx_flags_hi.putInt((int)(flagsToAdd >>> 32));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
            assert((flagsToAdd >>> 32) == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
        assert((h.flags & flagsToAdd) == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
            : (h+".flags="
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
                +Integer.toHexString(h.flags)+"^"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
                +Long.toHexString(flagsToAdd));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
    // temporary scratch variables for processing code blocks
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
    private Code                 curCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
    private Class                curClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
    private Entry[] curCPMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
    private void beginCode(Code c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
        assert(curCode == null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
        curCode = c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
        curClass = c.m.thisClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
        curCPMap = c.getCPMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
    private void endCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
        curCode = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
        curClass = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
        curCPMap = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
    // Return an _invokeinit_op variant, if the instruction matches one,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
    // else -1.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
    private int initOpVariant(Instruction i, Entry newClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
        if (i.getBC() != _invokespecial)  return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
        MemberEntry ref = (MemberEntry) i.getCPRef(curCPMap);
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1394
        if ("<init>".equals(ref.descRef.nameRef.stringValue()) == false)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
            return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
        ClassEntry refClass = ref.classRef;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
        if (refClass == curClass.thisClass)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
            return _invokeinit_op+_invokeinit_self_option;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
        if (refClass == curClass.superClass)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
            return _invokeinit_op+_invokeinit_super_option;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
        if (refClass == newClass)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
            return _invokeinit_op+_invokeinit_new_option;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
        return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
    // Return a _self_linker_op variant, if the instruction matches one,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
    // else -1.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
    private int selfOpVariant(Instruction i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
        int bc = i.getBC();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
        if (!(bc >= _first_linker_op && bc <= _last_linker_op))  return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
        MemberEntry ref = (MemberEntry) i.getCPRef(curCPMap);
16050
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1412
        // do not optimize this case, simply fall back to regular coding
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1413
        if ((bc == _invokespecial || bc == _invokestatic) &&
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1414
                ref.tagEquals(CONSTANT_InterfaceMethodref))
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1415
            return -1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
        ClassEntry refClass = ref.classRef;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
        int self_bc = _self_linker_op + (bc - _first_linker_op);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
        if (refClass == curClass.thisClass)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
            return self_bc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
        if (refClass == curClass.superClass)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
            return self_bc + _self_linker_super_flag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
        return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
    void writeByteCodes(Code code) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
        beginCode(code);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
        IndexGroup cp = pkg.cp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
        // true if the previous instruction is an aload to absorb
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
        boolean prevAload = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
        // class of most recent new; helps compress <init> calls
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
        Entry newClass = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
        for (Instruction i = code.instructionAt(0); i != null; i = i.next()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
            // %%% Add a stress mode which issues _ref/_byte_escape.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
            if (verbose > 3)  Utils.log.fine(i.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1439
            if (i.isNonstandard()) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
                // Crash and burn with a complaint if there are funny
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
                // bytecodes in this class file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
                String complaint = code.getMethod()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
                    +" contains an unrecognized bytecode "+i
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
                    +"; please use the pass-file option on this class.";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
                Utils.log.warning(complaint);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
                throw new IOException(complaint);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
            if (i.isWide()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
                if (verbose > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
                    Utils.log.fine("_wide opcode in "+code);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
                    Utils.log.fine(i.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
                bc_codes.putByte(_wide);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
                codeHist[_wide]++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
            int bc = i.getBC();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
            // Begin "bc_linker" compression.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
            if (bc == _aload_0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
                // Try to group aload_0 with a following operation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
                Instruction ni = code.instructionAt(i.getNextPC());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
                if (selfOpVariant(ni) >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
                    prevAload = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
            // Test for <init> invocations:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
            int init_bc = initOpVariant(i, newClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
            if (init_bc >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
                if (prevAload) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
                    // get rid of it
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
                    bc_codes.putByte(_aload_0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
                    codeHist[_aload_0]++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
                    prevAload = false;  //used up
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
                // Write special bytecode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
                bc_codes.putByte(init_bc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
                codeHist[init_bc]++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
                MemberEntry ref = (MemberEntry) i.getCPRef(curCPMap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
                // Write operand to a separate band.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
                int coding = cp.getOverloadingIndex(ref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
                bc_initref.putInt(coding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
            int self_bc = selfOpVariant(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
            if (self_bc >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
                boolean isField = Instruction.isFieldOp(bc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
                boolean isSuper = (self_bc >= _self_linker_op+_self_linker_super_flag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
                boolean isAload = prevAload;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
                prevAload = false;  //used up
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
                if (isAload)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
                    self_bc += _self_linker_aload_flag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
                // Write special bytecode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
                bc_codes.putByte(self_bc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
                codeHist[self_bc]++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
                // Write field or method ref to a separate band.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
                MemberEntry ref = (MemberEntry) i.getCPRef(curCPMap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
                CPRefBand bc_which = selfOpRefBand(self_bc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
                Index which_ix = cp.getMemberIndex(ref.tag, ref.classRef);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
                bc_which.putRef(ref, which_ix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
            assert(!prevAload);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
            // End "bc_linker" compression.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
            // Normal bytecode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
            codeHist[bc]++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
            switch (bc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
            case _tableswitch: // apc:  (df, lo, hi, (hi-lo+1)*(label))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
            case _lookupswitch: // apc:  (df, nc, nc*(case, label))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
                bc_codes.putByte(bc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
                Instruction.Switch isw = (Instruction.Switch) i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
                // Note that we do not write the alignment bytes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
                int apc = isw.getAlignedPC();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
                int npc = isw.getNextPC();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
                // write a length specification into the bytecode stream
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
                int caseCount = isw.getCaseCount();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
                bc_case_count.putInt(caseCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
                putLabel(bc_label, code, i.getPC(), isw.getDefaultLabel());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1524
                for (int j = 0; j < caseCount; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
                    putLabel(bc_label, code, i.getPC(), isw.getCaseLabel(j));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1526
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1527
                // Transmit case values in their own band.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1528
                if (bc == _tableswitch) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1529
                    bc_case_value.putInt(isw.getCaseValue(0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1530
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1531
                    for (int j = 0; j < caseCount; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1532
                        bc_case_value.putInt(isw.getCaseValue(j));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1533
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1534
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1535
                // Done with the switch.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1536
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1537
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1538
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1539
            int branch = i.getBranchLabel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1540
            if (branch >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1541
                bc_codes.putByte(bc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1542
                putLabel(bc_label, code, i.getPC(), branch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1543
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1544
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1545
            Entry ref = i.getCPRef(curCPMap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1546
            if (ref != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1547
                if (bc == _new)  newClass = ref;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1548
                if (bc == _ldc)  ldcHist[ref.tag]++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1549
                CPRefBand bc_which;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1550
                int vbc = bc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1551
                switch (i.getCPTag()) {
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1552
                case CONSTANT_LoadableValue:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1553
                    switch (ref.tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1554
                    case CONSTANT_Integer:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1555
                        bc_which = bc_intref;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1556
                        switch (bc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1557
                        case _ldc:    vbc = _ildc; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1558
                        case _ldc_w:  vbc = _ildc_w; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1559
                        default:      assert(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1560
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1561
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1562
                    case CONSTANT_Float:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1563
                        bc_which = bc_floatref;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1564
                        switch (bc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1565
                        case _ldc:    vbc = _fldc; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1566
                        case _ldc_w:  vbc = _fldc_w; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1567
                        default:      assert(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1568
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1569
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1570
                    case CONSTANT_Long:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1571
                        bc_which = bc_longref;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1572
                        assert(bc == _ldc2_w);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1573
                        vbc = _lldc2_w;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1574
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1575
                    case CONSTANT_Double:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1576
                        bc_which = bc_doubleref;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1577
                        assert(bc == _ldc2_w);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1578
                        vbc = _dldc2_w;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1579
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1580
                    case CONSTANT_String:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1581
                        bc_which = bc_stringref;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1582
                        switch (bc) {
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1583
                        case _ldc:    vbc = _sldc; break;
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1584
                        case _ldc_w:  vbc = _sldc_w; break;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1585
                        default:      assert(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1586
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1587
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1588
                    case CONSTANT_Class:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1589
                        bc_which = bc_classref;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1590
                        switch (bc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1591
                        case _ldc:    vbc = _cldc; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1592
                        case _ldc_w:  vbc = _cldc_w; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1593
                        default:      assert(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1594
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1595
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1596
                    default:
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1597
                        // CONSTANT_MethodHandle, etc.
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
  1598
                        if (getHighestClassVersion().lessThan(JAVA7_MAX_CLASS_VERSION)) {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
  1599
                            throw new IOException("bad class file major version for Java 7 ldc");
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1600
                        }
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1601
                        bc_which = bc_loadablevalueref;
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1602
                        switch (bc) {
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1603
                        case _ldc:    vbc = _qldc; break;
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1604
                        case _ldc_w:  vbc = _qldc_w; break;
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1605
                        default:      assert(false);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1606
                        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1607
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1608
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1609
                case CONSTANT_Class:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1610
                    // Use a special shorthand for the current class:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1611
                    if (ref == curClass.thisClass)  ref = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1612
                    bc_which = bc_classref; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1613
                case CONSTANT_Fieldref:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1614
                    bc_which = bc_fieldref; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1615
                case CONSTANT_Methodref:
16050
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1616
                    if (ref.tagEquals(CONSTANT_InterfaceMethodref)) {
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1617
                        if (bc == _invokespecial)
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1618
                            vbc = _invokespecial_int;
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1619
                        if (bc == _invokestatic)
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1620
                            vbc = _invokestatic_int;
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1621
                        bc_which = bc_imethodref;
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1622
                    } else {
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1623
                        bc_which = bc_methodref;
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1624
                    }
1eee624cddb3 8007297: [pack200] allow opcodes with InterfaceMethodRefs
ksrini
parents: 15526
diff changeset
  1625
                    break;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1626
                case CONSTANT_InterfaceMethodref:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1627
                    bc_which = bc_imethodref; break;
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1628
                case CONSTANT_InvokeDynamic:
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1629
                    bc_which = bc_indyref; break;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1630
                default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1631
                    bc_which = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1632
                    assert(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1633
                }
15526
84de8685a2d0 8003549: (pack200) assertion errors when processing lambda class files with IMethods
ksrini
parents: 15261
diff changeset
  1634
                if (ref != null && bc_which.index != null && !bc_which.index.contains(ref)) {
84de8685a2d0 8003549: (pack200) assertion errors when processing lambda class files with IMethods
ksrini
parents: 15261
diff changeset
  1635
                    // Crash and burn with a complaint if there are funny
84de8685a2d0 8003549: (pack200) assertion errors when processing lambda class files with IMethods
ksrini
parents: 15261
diff changeset
  1636
                    // references for this bytecode instruction.
84de8685a2d0 8003549: (pack200) assertion errors when processing lambda class files with IMethods
ksrini
parents: 15261
diff changeset
  1637
                    // Example:  invokestatic of a CONSTANT_InterfaceMethodref.
84de8685a2d0 8003549: (pack200) assertion errors when processing lambda class files with IMethods
ksrini
parents: 15261
diff changeset
  1638
                    String complaint = code.getMethod() +
84de8685a2d0 8003549: (pack200) assertion errors when processing lambda class files with IMethods
ksrini
parents: 15261
diff changeset
  1639
                        " contains a bytecode " + i +
84de8685a2d0 8003549: (pack200) assertion errors when processing lambda class files with IMethods
ksrini
parents: 15261
diff changeset
  1640
                        " with an unsupported constant reference; please use the pass-file option on this class.";
84de8685a2d0 8003549: (pack200) assertion errors when processing lambda class files with IMethods
ksrini
parents: 15261
diff changeset
  1641
                    Utils.log.warning(complaint);
84de8685a2d0 8003549: (pack200) assertion errors when processing lambda class files with IMethods
ksrini
parents: 15261
diff changeset
  1642
                    throw new IOException(complaint);
84de8685a2d0 8003549: (pack200) assertion errors when processing lambda class files with IMethods
ksrini
parents: 15261
diff changeset
  1643
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1644
                bc_codes.putByte(vbc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1645
                bc_which.putRef(ref);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1646
                // handle trailing junk
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1647
                if (bc == _multianewarray) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1648
                    assert(i.getConstant() == code.getByte(i.getPC()+3));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1649
                    // Just dump the byte into the bipush pile
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1650
                    bc_byte.putByte(0xFF & i.getConstant());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1651
                } else if (bc == _invokeinterface) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1652
                    assert(i.getLength() == 5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1653
                    // Make sure the discarded bytes are sane:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1654
                    assert(i.getConstant() == (1+((MemberEntry)ref).descRef.typeRef.computeSize(true)) << 8);
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1655
                } else if (bc == _invokedynamic) {
12857
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
  1656
                    if (getHighestClassVersion().lessThan(JAVA7_MAX_CLASS_VERSION)) {
0a5f341c2a28 7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present
ksrini
parents: 12544
diff changeset
  1657
                        throw new IOException("bad class major version for Java 7 invokedynamic");
12544
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1658
                    }
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1659
                    assert(i.getLength() == 5);
5768f2e096de 6981776: Pack200 must support -target 7 bytecodes
ksrini
parents: 10135
diff changeset
  1660
                    assert(i.getConstant() == 0);  // last 2 bytes MBZ
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1661
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1662
                    // Make sure there is nothing else to write.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1663
                    assert(i.getLength() == ((bc == _ldc)?2:3));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1664
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1665
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1666
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1667
            int slot = i.getLocalSlot();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1668
            if (slot >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1669
                bc_codes.putByte(bc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1670
                bc_local.putInt(slot);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1671
                int con = i.getConstant();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1672
                if (bc == _iinc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1673
                    if (!i.isWide()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1674
                        bc_byte.putByte(0xFF & con);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1675
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1676
                        bc_short.putInt(0xFFFF & con);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1677
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1678
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1679
                    assert(con == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1680
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1681
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1682
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1683
            // Generic instruction.  Copy the body.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1684
            bc_codes.putByte(bc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1685
            int pc = i.getPC()+1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1686
            int npc = i.getNextPC();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1687
            if (pc < npc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1688
                // Do a few remaining multi-byte instructions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1689
                switch (bc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1690
                case _sipush:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1691
                    bc_short.putInt(0xFFFF & i.getConstant());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1692
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1693
                case _bipush:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1694
                    bc_byte.putByte(0xFF & i.getConstant());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1695
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1696
                case _newarray:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1697
                    bc_byte.putByte(0xFF & i.getConstant());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1698
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1699
                default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1700
                    assert(false);  // that's it
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1701
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1702
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1703
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1704
        bc_codes.putByte(_end_marker);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1705
        bc_codes.elementCountForDebug++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1706
        codeHist[_end_marker]++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1707
        endCode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1708
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1709
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1710
    int[] codeHist = new int[1<<8];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1711
    int[] ldcHist  = new int[20];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1712
    void printCodeHist() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1713
        assert(verbose > 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1714
        String[] hist = new String[codeHist.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1715
        int totalBytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1716
        for (int bc = 0; bc < codeHist.length; bc++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1717
            totalBytes += codeHist[bc];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1718
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1719
        for (int bc = 0; bc < codeHist.length; bc++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1720
            if (codeHist[bc] == 0) { hist[bc] = ""; continue; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1721
            String iname = Instruction.byteName(bc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1722
            String count = "" + codeHist[bc];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1723
            count = "         ".substring(count.length()) + count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1724
            String pct = "" + (codeHist[bc] * 10000 / totalBytes);
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1725
            while (pct.length() < 4) {
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1726
                pct = "0" + pct;
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1727
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1728
            pct = pct.substring(0, pct.length()-2) + "." + pct.substring(pct.length()-2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1729
            hist[bc] = count + "  " + pct + "%  " + iname;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1730
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1731
        Arrays.sort(hist);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1732
        System.out.println("Bytecode histogram ["+totalBytes+"]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1733
        for (int i = hist.length; --i >= 0; ) {
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
  1734
            if ("".equals(hist[i]))  continue;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1735
            System.out.println(hist[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1736
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1737
        for (int tag = 0; tag < ldcHist.length; tag++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1738
            int count = ldcHist[tag];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1739
            if (count == 0)  continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1740
            System.out.println("ldc "+ConstantPool.tagName(tag)+" "+count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1741
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1742
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1743
}