hotspot/src/share/vm/classfile/imageFile.cpp
author chegar
Wed, 03 Dec 2014 14:21:14 +0000
changeset 27562 47f369e3c69c
child 27926 0e2e188ab887
permissions -rw-r--r--
8049367: Modular Run-Time Images Reviewed-by: chegar, dfuchs, ihse, joehw, mullan, psandoz, wetmore Contributed-by: alan.bateman@oracle.com, alex.buckley@oracle.com, bradford.wetmore@oracle.com, chris.hegarty@oracle.com, erik.joelsson@oracle.com, james.laskey@oracle.com, jonathan.gibbons@oracle.com, karen.kinnear@oracle.com, magnus.ihse.bursie@oracle.com, mandy.chung@oracle.com, mark.reinhold@oracle.com, paul.sandoz@oracle.com, sundararajan.athijegannathan@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
27562
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     1
/*
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     2
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     4
 *
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     7
 * published by the Free Software Foundation.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     8
 *
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    13
 * accompanied this code).
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    14
 *
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    18
 *
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    21
 * questions.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    22
 *
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    23
 */
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    24
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    25
#include "precompiled.hpp"
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    26
#include "classfile/imageFile.hpp"
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    27
#include "runtime/os.inline.hpp"
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    28
#include "utilities/bytes.hpp"
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    29
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    30
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    31
// Compute the Perfect Hashing hash code for the supplied string.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    32
u4 ImageStrings::hash_code(const char* string, u4 seed) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    33
  u1* bytes = (u1*)string;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    34
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    35
  // Compute hash code.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    36
  for (u1 byte = *bytes++; byte; byte = *bytes++) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    37
    seed = (seed * HASH_MULTIPLIER) ^ byte;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    38
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    39
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    40
  // Ensure the result is unsigned.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    41
  return seed & 0x7FFFFFFF;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    42
}
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    43
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    44
// Test to see if string begins with start.  If so returns remaining portion
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    45
// of string.  Otherwise, NULL.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    46
const char* ImageStrings::starts_with(const char* string, const char* start) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    47
  char ch1, ch2;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    48
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    49
  // Match up the strings the best we can.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    50
  while ((ch1 = *string) && (ch2 = *start)) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    51
    if (ch1 != ch2) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    52
      // Mismatch, return NULL.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    53
      return NULL;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    54
    }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    55
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    56
    string++, start++;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    57
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    58
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    59
  // Return remainder of string.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    60
  return string;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    61
}
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    62
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    63
ImageLocation::ImageLocation(u1* data) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    64
  // Deflate the attribute stream into an array of attributes.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    65
  memset(_attributes, 0, sizeof(_attributes));
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    66
  u1 byte;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    67
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    68
  while ((byte = *data) != ATTRIBUTE_END) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    69
    u1 kind = attribute_kind(byte);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    70
    u1 n = attribute_length(byte);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    71
    assert(kind < ATTRIBUTE_COUNT, "invalid image location attribute");
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    72
    _attributes[kind] = attribute_value(data + 1, n);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    73
    data += n + 1;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    74
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    75
}
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    76
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    77
ImageFile::ImageFile(const char* name) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    78
  // Copy the image file name.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    79
  _name = NEW_C_HEAP_ARRAY(char, strlen(name)+1, mtClass);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    80
  strcpy(_name, name);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    81
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    82
  // Initialize for a closed file.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    83
  _fd = -1;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    84
  _memory_mapped = true;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    85
  _index_data = NULL;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    86
}
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    87
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    88
ImageFile::~ImageFile() {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    89
  // Ensure file is closed.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    90
  close();
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    91
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    92
  // Free up name.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    93
  FREE_C_HEAP_ARRAY(char, _name, mtClass);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    94
}
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    95
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    96
bool ImageFile::open() {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    97
  // If file exists open for reading.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    98
  struct stat st;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    99
  if (os::stat(_name, &st) != 0 ||
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   100
    (st.st_mode & S_IFREG) != S_IFREG ||
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   101
    (_fd = os::open(_name, 0, O_RDONLY)) == -1) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   102
    return false;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   103
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   104
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   105
  // Read image file header and verify.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   106
  u8 header_size = sizeof(ImageHeader);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   107
  if (os::read(_fd, &_header, header_size) != header_size ||
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   108
    _header._magic != IMAGE_MAGIC ||
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   109
    _header._major_version != MAJOR_VERSION ||
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   110
    _header._minor_version != MINOR_VERSION) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   111
    close();
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   112
    return false;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   113
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   114
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   115
  // Memory map index.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   116
  _index_size = index_size();
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   117
  _index_data = (u1*)os::map_memory(_fd, _name, 0, NULL, _index_size, true, false);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   118
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   119
  // Failing that, read index into C memory.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   120
  if (_index_data == NULL) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   121
    _memory_mapped = false;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   122
    _index_data = NEW_RESOURCE_ARRAY(u1, _index_size);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   123
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   124
    if (os::seek_to_file_offset(_fd, 0) == -1) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   125
      close();
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   126
      return false;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   127
    }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   128
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   129
    if (os::read(_fd, _index_data, _index_size) != _index_size) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   130
      close();
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   131
      return false;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   132
    }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   133
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   134
    return true;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   135
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   136
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   137
// Used to advance a pointer, unstructured.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   138
#undef nextPtr
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   139
#define nextPtr(base, fromType, count, toType) (toType*)((fromType*)(base) + (count))
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   140
  // Pull tables out from the index.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   141
  _redirect_table = nextPtr(_index_data, u1, header_size, s4);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   142
  _offsets_table = nextPtr(_redirect_table, s4, _header._location_count, u4);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   143
  _location_bytes = nextPtr(_offsets_table, u4, _header._location_count, u1);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   144
  _string_bytes = nextPtr(_location_bytes, u1, _header._locations_size, u1);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   145
#undef nextPtr
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   146
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   147
  // Successful open.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   148
  return true;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   149
}
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   150
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   151
void ImageFile::close() {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   152
  // Dealllocate the index.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   153
  if (_index_data) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   154
    if (_memory_mapped) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   155
      os::unmap_memory((char*)_index_data, _index_size);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   156
    } else {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   157
      FREE_RESOURCE_ARRAY(u1, _index_data, _index_size);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   158
    }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   159
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   160
    _index_data = NULL;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   161
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   162
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   163
  // close file.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   164
  if (_fd != -1) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   165
    os::close(_fd);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   166
    _fd = -1;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   167
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   168
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   169
}
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   170
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   171
// Return the attribute stream for a named resourced.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   172
u1* ImageFile::find_location_data(const char* path) const {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   173
  // Compute hash.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   174
  u4 hash = ImageStrings::hash_code(path) % _header._location_count;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   175
  s4 redirect = _redirect_table[hash];
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   176
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   177
  if (!redirect) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   178
    return NULL;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   179
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   180
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   181
  u4 index;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   182
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   183
  if (redirect < 0) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   184
    // If no collision.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   185
    index = -redirect - 1;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   186
  } else {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   187
    // If collision, recompute hash code.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   188
    index = ImageStrings::hash_code(path, redirect) % _header._location_count;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   189
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   190
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   191
  assert(index < _header._location_count, "index exceeds location count");
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   192
  u4 offset = _offsets_table[index];
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   193
  assert(offset < _header._locations_size, "offset exceeds location attributes size");
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   194
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   195
  if (offset == 0) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   196
    return NULL;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   197
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   198
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   199
  return _location_bytes + offset;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   200
}
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   201
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   202
// Verify that a found location matches the supplied path.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   203
bool ImageFile::verify_location(ImageLocation& location, const char* path) const {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   204
  // Retrieve each path component string.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   205
  ImageStrings strings(_string_bytes, _header._strings_size);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   206
  // Match a path with each subcomponent without concatenation (copy).
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   207
  // Match up path parent.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   208
  const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   209
  const char* next = ImageStrings::starts_with(path, parent);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   210
  // Continue only if a complete match.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   211
  if (!next) return false;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   212
  // Match up path base.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   213
  const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   214
  next = ImageStrings::starts_with(next, base);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   215
  // Continue only if a complete match.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   216
  if (!next) return false;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   217
  // Match up path extension.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   218
  const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   219
  next = ImageStrings::starts_with(next, extension);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   220
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   221
  // True only if complete match and no more characters.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   222
  return next && *next == '\0';
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   223
}
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   224
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   225
// Return the resource for the supplied location.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   226
u1* ImageFile::get_resource(ImageLocation& location) const {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   227
  // Retrieve the byte offset and size of the resource.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   228
  u8 offset = _index_size + location.get_attribute(ImageLocation::ATTRIBUTE_OFFSET);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   229
  u8 size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   230
  u8 compressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_COMPRESSED);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   231
  u8 read_size = compressed_size ? compressed_size : size;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   232
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   233
  // Allocate space for the resource.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   234
  u1* data = NEW_RESOURCE_ARRAY(u1, read_size);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   235
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   236
  bool is_read = os::read_at(_fd, data, read_size, offset) == read_size;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   237
  guarantee(is_read, "error reading from image or short read");
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   238
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   239
  // If not compressed, just return the data.
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   240
  if (!compressed_size) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   241
    return data;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   242
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   243
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   244
  u1* uncompressed = NEW_RESOURCE_ARRAY(u1, size);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   245
  char* msg = NULL;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   246
  jboolean res = ClassLoader::decompress(data, compressed_size, uncompressed, size, &msg);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   247
  if (!res) warning("decompression failed due to %s\n", msg);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   248
  guarantee(res, "decompression failed");
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   249
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   250
  return uncompressed;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   251
}
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   252
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   253
void ImageFile::get_resource(const char* path, u1*& buffer, u8& size) const {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   254
  buffer = NULL;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   255
  size = 0;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   256
  u1* data = find_location_data(path);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   257
  if (data) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   258
    ImageLocation location(data);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   259
    if (verify_location(location, path)) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   260
      size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   261
      buffer = get_resource(location);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   262
    }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   263
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   264
}
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   265
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   266
GrowableArray<const char*>* ImageFile::packages(const char* name) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   267
  char entry[JVM_MAXPATHLEN];
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   268
  bool overflow = jio_snprintf(entry, sizeof(entry), "%s/packages.offsets", name) == -1;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   269
  guarantee(!overflow, "package name overflow");
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   270
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   271
  u1* buffer;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   272
  u8 size;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   273
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   274
  get_resource(entry, buffer, size);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   275
  guarantee(buffer, "missing module packages reource");
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   276
  ImageStrings strings(_string_bytes, _header._strings_size);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   277
  GrowableArray<const char*>* pkgs = new GrowableArray<const char*>();
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   278
  int count = size / 4;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   279
  for (int i = 0; i < count; i++) {
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   280
    u4 offset = Bytes::get_Java_u4(buffer + (i*4));
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   281
    const char* p = strings.get(offset);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   282
    pkgs->append(p);
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   283
  }
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   284
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   285
  return pkgs;
47f369e3c69c 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   286
}