src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java
author erikj
Wed, 07 Mar 2018 13:26:15 -0800
changeset 49357 aaedb8343784
parent 47216 71c04702a3d5
permissions -rw-r--r--
8198243: Add build time check for global operator new/delete in object files Reviewed-by: tbell, kbarrett, dholmes, ihse
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     1
/*
43795
526103bd9c57 8169715: jimage fails with IAE when attempts to inspect an empty file
dkononenko
parents: 41121
diff changeset
     2
 * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     4
 *
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    10
 *
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    15
 * accompanied this code).
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    16
 *
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    20
 *
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    23
 * questions.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    24
 */
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    25
package jdk.internal.jimage;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    26
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
    27
import java.io.ByteArrayInputStream;
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    28
import java.io.IOException;
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
    29
import java.io.InputStream;
38445
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
    30
import java.lang.reflect.InvocationTargetException;
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
    31
import java.lang.reflect.Method;
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    32
import java.nio.ByteBuffer;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    33
import java.nio.ByteOrder;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    34
import java.nio.IntBuffer;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    35
import java.nio.channels.FileChannel;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    36
import java.nio.file.Path;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    37
import java.nio.file.StandardOpenOption;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    38
import java.security.AccessController;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    39
import java.security.PrivilegedAction;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    40
import java.util.Objects;
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
    41
import java.util.stream.IntStream;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    42
import jdk.internal.jimage.decompressor.Decompressor;
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    43
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    44
/**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    45
 * @implNote This class needs to maintain JDK 8 source compatibility.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    46
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    47
 * It is used internally in the JDK to implement jimage/jrtfs access,
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    48
 * but also compiled and delivered as part of the jrtfs.jar to support access
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    49
 * to the jimage file provided by the shipped JDK by tools running on JDK 8.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    50
 */
32641
ac2c73b45253 8087181: Move native jimage code to its own library (maybe libjimage)
jlaskey
parents: 31673
diff changeset
    51
public class BasicImageReader implements AutoCloseable {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    52
    private static boolean isSystemProperty(String key, String value, String def) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    53
        // No lambdas during bootstrap
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    54
        return AccessController.doPrivileged(
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    55
            new PrivilegedAction<Boolean>() {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    56
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    57
                public Boolean run() {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    58
                    return value.equals(System.getProperty(key, def));
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    59
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    60
            });
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    61
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    62
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    63
    static private final boolean IS_64_BIT =
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    64
            isSystemProperty("sun.arch.data.model", "64", "32");
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    65
    static private final boolean USE_JVM_MAP =
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    66
            isSystemProperty("jdk.image.use.jvm.map", "true", "true");
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    67
    static private final boolean MAP_ALL =
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    68
            isSystemProperty("jdk.image.map.all", "true", IS_64_BIT ? "true" : "false");
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    69
38582
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
    70
    private final Path imagePath;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    71
    private final ByteOrder byteOrder;
38582
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
    72
    private final String name;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    73
    private final ByteBuffer memoryMap;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    74
    private final FileChannel channel;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    75
    private final ImageHeader header;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    76
    private final long indexSize;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    77
    private final IntBuffer redirect;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    78
    private final IntBuffer offsets;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    79
    private final ByteBuffer locations;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    80
    private final ByteBuffer strings;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    81
    private final ImageStringsReader stringsReader;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    82
    private final Decompressor decompressor;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    83
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    84
    protected BasicImageReader(Path path, ByteOrder byteOrder)
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    85
            throws IOException {
38582
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
    86
        this.imagePath = Objects.requireNonNull(path);
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
    87
        this.byteOrder = Objects.requireNonNull(byteOrder);
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
    88
        this.name = this.imagePath.toString();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    89
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    90
        ByteBuffer map;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    91
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    92
        if (USE_JVM_MAP && BasicImageReader.class.getClassLoader() == null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    93
            // Check to see if the jvm has opened the file using libjimage
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    94
            // native entry when loading the image for this runtime
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    95
            map = NativeImageBuffer.getNativeMap(name);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    96
         } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    97
            map = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    98
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
    99
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   100
        // Open the file only if no memory map yet or is 32 bit jvm
38445
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   101
        if (map != null && MAP_ALL) {
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   102
            channel = null;
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   103
        } else {
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   104
            channel = FileChannel.open(imagePath, StandardOpenOption.READ);
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   105
            // No lambdas during bootstrap
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   106
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   107
                @Override
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   108
                public Void run() {
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   109
                    if (BasicImageReader.class.getClassLoader() == null) {
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   110
                        try {
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   111
                            Class<?> fileChannelImpl =
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   112
                                Class.forName("sun.nio.ch.FileChannelImpl");
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   113
                            Method setUninterruptible =
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   114
                                    fileChannelImpl.getMethod("setUninterruptible");
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   115
                            setUninterruptible.invoke(channel);
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   116
                        } catch (ClassNotFoundException |
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   117
                                 NoSuchMethodException |
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   118
                                 IllegalAccessException |
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   119
                                 InvocationTargetException ex) {
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   120
                            // fall thru - will only happen on JDK-8 systems where this code
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   121
                            // is only used by tools using jrt-fs (non-critical.)
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   122
                        }
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   123
                    }
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   124
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   125
                    return null;
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   126
                }
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   127
            });
0a88d86065f9 8156602: javac crashes again on Windows 32-bit with ClosedChannelException
jlaskey
parents: 37617
diff changeset
   128
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   129
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   130
        // If no memory map yet and 64 bit jvm then memory map entire file
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   131
        if (MAP_ALL && map == null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   132
            map = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   133
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   134
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   135
        // Assume we have a memory map to read image file header
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   136
        ByteBuffer headerBuffer = map;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   137
        int headerSize = ImageHeader.getHeaderSize();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   138
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   139
        // If no memory map then read header from image file
43795
526103bd9c57 8169715: jimage fails with IAE when attempts to inspect an empty file
dkononenko
parents: 41121
diff changeset
   140
        if (headerBuffer == null) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   141
            headerBuffer = ByteBuffer.allocateDirect(headerSize);
43795
526103bd9c57 8169715: jimage fails with IAE when attempts to inspect an empty file
dkononenko
parents: 41121
diff changeset
   142
            if (channel.read(headerBuffer, 0L) == headerSize) {
526103bd9c57 8169715: jimage fails with IAE when attempts to inspect an empty file
dkononenko
parents: 41121
diff changeset
   143
                headerBuffer.rewind();
526103bd9c57 8169715: jimage fails with IAE when attempts to inspect an empty file
dkononenko
parents: 41121
diff changeset
   144
            } else {
526103bd9c57 8169715: jimage fails with IAE when attempts to inspect an empty file
dkononenko
parents: 41121
diff changeset
   145
                throw new IOException("\"" + name + "\" is not an image file");
526103bd9c57 8169715: jimage fails with IAE when attempts to inspect an empty file
dkononenko
parents: 41121
diff changeset
   146
            }
526103bd9c57 8169715: jimage fails with IAE when attempts to inspect an empty file
dkononenko
parents: 41121
diff changeset
   147
        } else if (headerBuffer.capacity() < headerSize) {
526103bd9c57 8169715: jimage fails with IAE when attempts to inspect an empty file
dkononenko
parents: 41121
diff changeset
   148
            throw new IOException("\"" + name + "\" is not an image file");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   149
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   150
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   151
        // Interpret the image file header
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   152
        header = readHeader(intBuffer(headerBuffer, 0, headerSize));
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   153
        indexSize = header.getIndexSize();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   154
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   155
        // If no memory map yet then must be 32 bit jvm not previously mapped
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   156
        if (map == null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   157
            // Just map the image index
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   158
            map = channel.map(FileChannel.MapMode.READ_ONLY, 0, indexSize);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   159
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   160
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   161
        memoryMap = map.asReadOnlyBuffer();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   162
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   163
        // Interpret the image index
43795
526103bd9c57 8169715: jimage fails with IAE when attempts to inspect an empty file
dkononenko
parents: 41121
diff changeset
   164
        if (memoryMap.capacity() < indexSize) {
526103bd9c57 8169715: jimage fails with IAE when attempts to inspect an empty file
dkononenko
parents: 41121
diff changeset
   165
            throw new IOException("The image file \"" + name + "\" is corrupted");
526103bd9c57 8169715: jimage fails with IAE when attempts to inspect an empty file
dkononenko
parents: 41121
diff changeset
   166
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   167
        redirect = intBuffer(memoryMap, header.getRedirectOffset(), header.getRedirectSize());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   168
        offsets = intBuffer(memoryMap, header.getOffsetsOffset(), header.getOffsetsSize());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   169
        locations = slice(memoryMap, header.getLocationsOffset(), header.getLocationsSize());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   170
        strings = slice(memoryMap, header.getStringsOffset(), header.getStringsSize());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   171
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   172
        stringsReader = new ImageStringsReader(this);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   173
        decompressor = new Decompressor();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   174
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   175
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   176
    protected BasicImageReader(Path imagePath) throws IOException {
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   177
        this(imagePath, ByteOrder.nativeOrder());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   178
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   179
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   180
    public static BasicImageReader open(Path imagePath) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   181
        return new BasicImageReader(imagePath, ByteOrder.nativeOrder());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   182
    }
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   183
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   184
    public ImageHeader getHeader() {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   185
        return header;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   186
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   187
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   188
    private ImageHeader readHeader(IntBuffer buffer) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   189
        ImageHeader result = ImageHeader.readFrom(buffer);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   190
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   191
        if (result.getMagic() != ImageHeader.MAGIC) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   192
            throw new IOException("\"" + name + "\" is not an image file");
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   193
        }
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   194
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   195
        if (result.getMajorVersion() != ImageHeader.MAJOR_VERSION ||
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   196
            result.getMinorVersion() != ImageHeader.MINOR_VERSION) {
41121
91734a3ed04b 8151832: Improve exception messages in exception thrown by new JDK 9 code
coffeys
parents: 38582
diff changeset
   197
            throw new IOException("The image file \"" + name + "\" is not " +
91734a3ed04b 8151832: Improve exception messages in exception thrown by new JDK 9 code
coffeys
parents: 38582
diff changeset
   198
                "the correct version. Major: " + result.getMajorVersion() +
91734a3ed04b 8151832: Improve exception messages in exception thrown by new JDK 9 code
coffeys
parents: 38582
diff changeset
   199
                ". Minor: " + result.getMinorVersion());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   200
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   201
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   202
        return result;
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   203
    }
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   204
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   205
    private static ByteBuffer slice(ByteBuffer buffer, int position, int capacity) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   206
        // Note that this is the only limit and position manipulation of
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   207
        // BasicImageReader private ByteBuffers.  The synchronize could be avoided
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   208
        // by cloning the buffer to make a local copy, but at the cost of creating
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   209
        // a new object.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   210
        synchronized(buffer) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   211
            buffer.limit(position + capacity);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   212
            buffer.position(position);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   213
            return buffer.slice();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   214
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   215
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   216
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   217
    private IntBuffer intBuffer(ByteBuffer buffer, int offset, int size) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   218
        return slice(buffer, offset, size).order(byteOrder).asIntBuffer();
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   219
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   220
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   221
    public static void releaseByteBuffer(ByteBuffer buffer) {
38582
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   222
        Objects.requireNonNull(buffer);
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   223
37617
d91c47cb2992 8154179: BasicImageReader activating ImageBufferCache when not used
jlaskey
parents: 37342
diff changeset
   224
        if (!MAP_ALL) {
d91c47cb2992 8154179: BasicImageReader activating ImageBufferCache when not used
jlaskey
parents: 37342
diff changeset
   225
            ImageBufferCache.releaseBuffer(buffer);
d91c47cb2992 8154179: BasicImageReader activating ImageBufferCache when not used
jlaskey
parents: 37342
diff changeset
   226
        }
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   227
    }
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   228
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   229
    public String getName() {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   230
        return name;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   231
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   232
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   233
    public ByteOrder getByteOrder() {
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   234
        return byteOrder;
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   235
    }
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   236
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   237
    public Path getImagePath() {
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   238
        return imagePath;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   239
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   240
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   241
    @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   242
    public void close() throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   243
        if (channel != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   244
            channel.close();
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   245
        }
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   246
    }
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   247
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   248
    public ImageStringsReader getStrings() {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   249
        return stringsReader;
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   250
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   251
44034
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   252
    public synchronized ImageLocation findLocation(String module, String name) {
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   253
        Objects.requireNonNull(module);
38582
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   254
        Objects.requireNonNull(name);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   255
        // Details of the algorithm used here can be found in
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   256
        // jdk.tools.jlink.internal.PerfectHashBuilder.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   257
        int count = header.getTableLength();
44034
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   258
        int index = redirect.get(ImageStringsReader.hashCode(module, name) % count);
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   259
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   260
        if (index < 0) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   261
            // index is twos complement of location attributes index.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   262
            index = -index - 1;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   263
        } else if (index > 0) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   264
            // index is hash seed needed to compute location attributes index.
44034
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   265
            index = ImageStringsReader.hashCode(module, name, index) % count;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   266
        } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   267
            // No entry.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   268
            return null;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   269
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   270
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   271
        long[] attributes = getAttributes(offsets.get(index));
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   272
44034
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   273
        if (!ImageLocation.verify(module, name, attributes, stringsReader)) {
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   274
            return null;
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   275
        }
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   276
        return new ImageLocation(attributes, stringsReader);
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   277
    }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   278
44034
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   279
    public synchronized ImageLocation findLocation(String name) {
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   280
        Objects.requireNonNull(name);
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   281
        // Details of the algorithm used here can be found in
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   282
        // jdk.tools.jlink.internal.PerfectHashBuilder.
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   283
        int count = header.getTableLength();
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   284
        int index = redirect.get(ImageStringsReader.hashCode(name) % count);
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   285
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   286
        if (index < 0) {
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   287
            // index is twos complement of location attributes index.
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   288
            index = -index - 1;
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   289
        } else if (index > 0) {
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   290
            // index is hash seed needed to compute location attributes index.
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   291
            index = ImageStringsReader.hashCode(name, index) % count;
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   292
        } else {
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   293
            // No entry.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   294
            return null;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   295
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   296
44034
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   297
        long[] attributes = getAttributes(offsets.get(index));
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   298
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   299
        if (!ImageLocation.verify(name, attributes, stringsReader)) {
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   300
            return null;
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   301
        }
0d664fca91a7 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
redestad
parents: 43795
diff changeset
   302
        return new ImageLocation(attributes, stringsReader);
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   303
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   304
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   305
    public String[] getEntryNames() {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   306
        int[] attributeOffsets = new int[offsets.capacity()];
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   307
        offsets.get(attributeOffsets);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   308
        return IntStream.of(attributeOffsets)
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   309
                        .filter(o -> o != 0)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   310
                        .mapToObj(o -> ImageLocation.readFrom(this, o).getFullName())
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   311
                        .sorted()
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   312
                        .toArray(String[]::new);
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   313
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   314
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   315
    ImageLocation getLocation(int offset) {
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   316
        return ImageLocation.readFrom(this, offset);
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   317
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   318
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   319
    public long[] getAttributes(int offset) {
38582
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   320
        if (offset < 0 || offset >= locations.limit()) {
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   321
            throw new IndexOutOfBoundsException("offset");
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   322
        }
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   323
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   324
        ByteBuffer buffer = slice(locations, offset, locations.limit() - offset);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   325
        return ImageLocation.decompress(buffer);
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   326
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   327
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   328
    public String getString(int offset) {
38582
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   329
        if (offset < 0 || offset >= strings.limit()) {
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   330
            throw new IndexOutOfBoundsException("offset");
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   331
        }
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   332
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   333
        ByteBuffer buffer = slice(strings, offset, strings.limit() - offset);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   334
        return ImageStringsReader.stringFromByteBuffer(buffer);
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   335
    }
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   336
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   337
    private byte[] getBufferBytes(ByteBuffer buffer) {
38582
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   338
        Objects.requireNonNull(buffer);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   339
        byte[] bytes = new byte[buffer.limit()];
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   340
        buffer.get(bytes);
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   341
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   342
        return bytes;
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   343
    }
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   344
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   345
    private ByteBuffer readBuffer(long offset, long size) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   346
        if (offset < 0 || Integer.MAX_VALUE <= offset) {
41121
91734a3ed04b 8151832: Improve exception messages in exception thrown by new JDK 9 code
coffeys
parents: 38582
diff changeset
   347
            throw new IndexOutOfBoundsException("Bad offset: " + offset);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   348
        }
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   349
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   350
        if (size < 0 || Integer.MAX_VALUE <= size) {
41121
91734a3ed04b 8151832: Improve exception messages in exception thrown by new JDK 9 code
coffeys
parents: 38582
diff changeset
   351
            throw new IndexOutOfBoundsException("Bad size: " + size);
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   352
        }
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   353
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   354
        if (MAP_ALL) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   355
            ByteBuffer buffer = slice(memoryMap, (int)offset, (int)size);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   356
            buffer.order(ByteOrder.BIG_ENDIAN);
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   357
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   358
            return buffer;
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   359
        } else {
37342
3f54fbfc2706 8151807: ImageBufferCache should release buffers when all classes are loaded
plevart
parents: 36511
diff changeset
   360
            if (channel == null) {
3f54fbfc2706 8151807: ImageBufferCache should release buffers when all classes are loaded
plevart
parents: 36511
diff changeset
   361
                throw new InternalError("Image file channel not open");
3f54fbfc2706 8151807: ImageBufferCache should release buffers when all classes are loaded
plevart
parents: 36511
diff changeset
   362
            }
3f54fbfc2706 8151807: ImageBufferCache should release buffers when all classes are loaded
plevart
parents: 36511
diff changeset
   363
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   364
            ByteBuffer buffer = ImageBufferCache.getBuffer(size);
37342
3f54fbfc2706 8151807: ImageBufferCache should release buffers when all classes are loaded
plevart
parents: 36511
diff changeset
   365
            int read;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   366
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   367
                read = channel.read(buffer, offset);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   368
                buffer.rewind();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   369
            } catch (IOException ex) {
37342
3f54fbfc2706 8151807: ImageBufferCache should release buffers when all classes are loaded
plevart
parents: 36511
diff changeset
   370
                ImageBufferCache.releaseBuffer(buffer);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   371
                throw new RuntimeException(ex);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   372
            }
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   373
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   374
            if (read != size) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   375
                ImageBufferCache.releaseBuffer(buffer);
37342
3f54fbfc2706 8151807: ImageBufferCache should release buffers when all classes are loaded
plevart
parents: 36511
diff changeset
   376
                throw new RuntimeException("Short read: " + read +
3f54fbfc2706 8151807: ImageBufferCache should release buffers when all classes are loaded
plevart
parents: 36511
diff changeset
   377
                                           " instead of " + size + " bytes");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   378
            }
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   379
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   380
            return buffer;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   381
        }
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   382
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   383
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   384
    public byte[] getResource(String name) {
38582
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   385
        Objects.requireNonNull(name);
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   386
        ImageLocation location = findLocation(name);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   387
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   388
        return location != null ? getResource(location) : null;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   389
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   390
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   391
    public byte[] getResource(ImageLocation loc) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   392
        ByteBuffer buffer = getResourceBuffer(loc);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   393
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   394
        if (buffer != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   395
            byte[] bytes = getBufferBytes(buffer);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   396
            ImageBufferCache.releaseBuffer(buffer);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   397
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   398
            return bytes;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   399
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   400
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   401
        return null;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   402
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   403
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   404
    public ByteBuffer getResourceBuffer(ImageLocation loc) {
38582
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   405
        Objects.requireNonNull(loc);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   406
        long offset = loc.getContentOffset() + indexSize;
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   407
        long compressedSize = loc.getCompressedSize();
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   408
        long uncompressedSize = loc.getUncompressedSize();
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   409
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   410
        if (compressedSize < 0 || Integer.MAX_VALUE < compressedSize) {
41121
91734a3ed04b 8151832: Improve exception messages in exception thrown by new JDK 9 code
coffeys
parents: 38582
diff changeset
   411
            throw new IndexOutOfBoundsException(
91734a3ed04b 8151832: Improve exception messages in exception thrown by new JDK 9 code
coffeys
parents: 38582
diff changeset
   412
                "Bad compressed size: " + compressedSize);
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   413
        }
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   414
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   415
        if (uncompressedSize < 0 || Integer.MAX_VALUE < uncompressedSize) {
41121
91734a3ed04b 8151832: Improve exception messages in exception thrown by new JDK 9 code
coffeys
parents: 38582
diff changeset
   416
            throw new IndexOutOfBoundsException(
91734a3ed04b 8151832: Improve exception messages in exception thrown by new JDK 9 code
coffeys
parents: 38582
diff changeset
   417
                "Bad uncompressed size: " + uncompressedSize);
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   418
        }
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   419
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   420
        if (compressedSize == 0) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   421
            return readBuffer(offset, uncompressedSize);
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   422
        } else {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   423
            ByteBuffer buffer = readBuffer(offset, compressedSize);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   424
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   425
            if (buffer != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   426
                byte[] bytesIn = getBufferBytes(buffer);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   427
                ImageBufferCache.releaseBuffer(buffer);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   428
                byte[] bytesOut;
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   429
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   430
                try {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   431
                    bytesOut = decompressor.decompressResource(byteOrder,
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   432
                            (int strOffset) -> getString(strOffset), bytesIn);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   433
                } catch (IOException ex) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   434
                    throw new RuntimeException(ex);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   435
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   436
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   437
                return ByteBuffer.wrap(bytesOut);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   438
            }
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   439
        }
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   440
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 32985
diff changeset
   441
        return null;
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   442
    }
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   443
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   444
    public InputStream getResourceStream(ImageLocation loc) {
38582
8618f4ccb220 8156209: Add argument checks to BasicImageReader calls
jlaskey
parents: 38445
diff changeset
   445
        Objects.requireNonNull(loc);
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   446
        byte[] bytes = getResource(loc);
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   447
31673
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   448
        return new ByteArrayInputStream(bytes);
135283550686 8080511: Refresh of jimage support
jfdenise
parents: 27565
diff changeset
   449
    }
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   450
}