hotspot/src/share/vm/classfile/imageDecompressor.hpp
author brutisso
Tue, 04 Aug 2015 12:58:54 +0200
changeset 32081 43cb85a46633
parent 31608 b5cb9a07591a
permissions -rw-r--r--
8132953: imageDecompressor.hpp should not include precompiled.hpp Reviewed-by: dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
31608
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
     1
/*
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
     2
 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
     4
 *
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
     7
 * published by the Free Software Foundation.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
     8
 *
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    13
 * accompanied this code).
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    14
 *
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    18
 *
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    21
 * questions.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    22
 *
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    23
 */
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    24
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    25
#ifndef SHARE_VM_CLASSFILE_IMAGEDECOMPRESSOR_HPP
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    26
#define SHARE_VM_CLASSFILE_IMAGEDECOMPRESSOR_HPP
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    27
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    28
#include "runtime/thread.inline.hpp"
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    29
#include "classfile/classLoader.hpp"
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    30
#include "classfile/imageFile.hpp"
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    31
#include "classfile/symbolTable.hpp"
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    32
#include "oops/symbol.hpp"
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    33
#include "utilities/growableArray.hpp"
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    34
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    35
/*
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    36
 * Compressed resources located in image have an header.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    37
 * This header contains:
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    38
 * - _magic: A magic u4, required to retrieved the header in the compressed content
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    39
 * - _size: The size of the compressed resource.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    40
 * - _uncompressed_size: The uncompressed size of the compressed resource.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    41
 * - _decompressor_name_offset: The ImageDecompressor instance name StringsTable offset.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    42
 * - _decompressor_config_offset: StringsTable offset of configuration that could be needed by
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    43
 *   the decompressor in order to decompress.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    44
 * - _is_terminal: 1: the compressed content is terminal. Uncompressing it would
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    45
 *   create the actual resource. 0: the compressed content is not terminal. Uncompressing it
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    46
 *   will result in a compressed content to be decompressed (This occurs when a stack of compressors
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    47
 *   have been used to compress the resource.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    48
 */
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    49
struct ResourceHeader {
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    50
  /* Length of header, needed to retrieve content offset */
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    51
  static const u1 resource_header_length = 21;
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    52
  /* magic bytes that identifies a compressed resource header*/
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    53
  static const u4 resource_header_magic = 0xCAFEFAFA;
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    54
  u4 _magic; // Resource header
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    55
  u4 _size;  // Resource size
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    56
  u4 _uncompressed_size;  // Expected uncompressed size
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    57
  u4 _decompressor_name_offset;  // Strings table decompressor offset
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    58
  u4 _decompressor_config_offset; // Strings table config offset
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    59
  u1 _is_terminal; // Last decompressor 1, otherwise 0.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    60
};
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    61
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    62
/*
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    63
 * Resources located in jimage file can be compressed. Compression occurs at
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    64
 * jimage file creation time. When compressed a resource is added an header that
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    65
 * contains the name of the compressor that compressed it.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    66
 * Various compression strategies can be applied to compress a resource.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    67
 * The same resource can even be compressed multiple time by a stack of compressors.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    68
 * At runtime, a resource is decompressed in a loop until there is no more header
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    69
 * meaning that the resource is equivalent to the not compressed resource.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    70
 * In each iteration, the name of the compressor located in the current header
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    71
 * is used to retrieve the associated instance of ImageDecompressor.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    72
 * For example “zip” is the name of the compressor that compresses resources
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    73
 * using the zip algorithm. The ZipDecompressor class name is also “zip”.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    74
 * ImageDecompressor instances are retrieved from a static array in which
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    75
 * they are registered.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    76
 */
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    77
class ImageDecompressor: public CHeapObj<mtClass> {
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    78
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    79
private:
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    80
  const Symbol* _name;
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    81
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    82
  /*
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    83
   * Array of concrete decompressors. This array is used to retrieve the decompressor
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    84
   * that can handle resource decompression.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    85
   */
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    86
  static GrowableArray<ImageDecompressor*>* _decompressors;
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    87
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    88
  /*
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    89
   * Identifier of a decompressor. This name is the identification key to retrieve
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    90
   * decompressor from a resource header.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    91
   */
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    92
  inline const Symbol* get_name() const { return _name; }
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    93
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    94
protected:
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    95
  ImageDecompressor(const Symbol* name) : _name(name) {
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    96
  }
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    97
  virtual void decompress_resource(u1* data, u1* uncompressed,
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    98
    ResourceHeader* header, const ImageStrings* strings) = 0;
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
    99
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   100
public:
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   101
  inline static void add_decompressor(ImageDecompressor* decompressor) {
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   102
    _decompressors->append(decompressor);
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   103
  }
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   104
  inline static ImageDecompressor* get_decompressor(const char * decompressor_name) {
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   105
    Thread* THREAD = Thread::current();
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   106
    TempNewSymbol sym = SymbolTable::new_symbol(decompressor_name,
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   107
            (int) strlen(decompressor_name), CHECK_NULL);
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   108
    if (HAS_PENDING_EXCEPTION) {
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   109
      warning("can't create symbol\n");
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   110
      CLEAR_PENDING_EXCEPTION;
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   111
      return NULL;
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   112
    }
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   113
    for (int i = 0; i < _decompressors->length(); i++) {
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   114
      ImageDecompressor* decompressor = _decompressors->at(i);
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   115
      if (decompressor->get_name()->fast_compare(sym) == 0) {
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   116
        return decompressor;
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   117
      }
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   118
    }
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   119
    guarantee(false, "No decompressor found.");
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   120
    return NULL;
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   121
  }
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   122
  static void decompress_resource(u1* compressed, u1* uncompressed,
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   123
    u4 uncompressed_size, const ImageStrings* strings, bool is_C_heap);
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   124
};
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   125
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   126
/**
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   127
 * Zip decompressor.
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   128
 */
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   129
class ZipDecompressor : public ImageDecompressor {
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   130
public:
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   131
  ZipDecompressor(const Symbol* sym) : ImageDecompressor(sym) { }
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   132
  void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header,
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   133
    const ImageStrings* strings);
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   134
};
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   135
b5cb9a07591a 8080511: Refresh of jimage support
jfdenise
parents:
diff changeset
   136
#endif // SHARE_VM_CLASSFILE_IMAGEDECOMPRESSOR_HPP