hotspot/src/share/vm/memory/filemap.cpp
author ysr
Wed, 07 Sep 2011 13:55:42 -0700
changeset 10526 3e92f211533f
parent 7405 e6fc8d3926f8
child 13728 882756847a04
permissions -rw-r--r--
4965777: GC changes to support use of discovered field for pending references Summary: If and when the reference handler thread is able to use the discovered field to link reference objects in its pending list, so will GC. In that case, GC will scan through this field once a reference object has been placed on the pending list, but not scan that field before that stage, as the field is used by the concurrent GC thread to link discovered objects. When ReferenceHandleR thread does not use the discovered field for the purpose of linking the elements in the pending list, as would be the case in older JDKs, the JVM will fall back to the old behaviour of using the next field for that purpose. Reviewed-by: jcoomes, mchung, stefank
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
     2
 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 2131
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 2131
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 2131
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    26
#include "classfile/classLoader.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    27
#include "classfile/symbolTable.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "memory/filemap.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    29
#include "runtime/arguments.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    30
#include "runtime/java.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    31
#include "runtime/os.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    32
#include "utilities/defaultStream.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    33
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
# include <sys/stat.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
# include <errno.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
#ifndef O_BINARY       // if defined (Win32) use binary files.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
#define O_BINARY 0     // otherwise do nothing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
extern address JVM_FunctionAtStart();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
extern address JVM_FunctionAtEnd();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1
diff changeset
    45
// Complain and stop. All error conditions occurring during the writing of
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
// an archive file should stop the process.  Unrecoverable errors during
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
// the reading of the archive file should stop the process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
static void fail(const char *msg, va_list ap) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  // This occurs very early during initialization: tty is not initialized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  jio_fprintf(defaultStream::error_stream(),
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1
diff changeset
    52
              "An error has occurred while processing the"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
              " shared archive file.\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  jio_vfprintf(defaultStream::error_stream(), msg, ap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  jio_fprintf(defaultStream::error_stream(), "\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  vm_exit_during_initialization("Unable to use shared archive.", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
void FileMapInfo::fail_stop(const char *msg, ...) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
        va_list ap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  va_start(ap, msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  fail(msg, ap);        // Never returns.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  va_end(ap);           // for completeness.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
// Complain and continue.  Recoverable errors during the reading of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
// archive file may continue (with sharing disabled).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
// If we continue, then disable shared spaces and close the file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
void FileMapInfo::fail_continue(const char *msg, ...) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  va_list ap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  va_start(ap, msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  if (RequireSharedSpaces) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
    fail(msg, ap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  va_end(ap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  UseSharedSpaces = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  close();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
// Fill in the fileMapInfo structure with data about this VM instance.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
void FileMapInfo::populate_header(size_t alignment) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  _header._magic = 0xf00baba2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  _header._version = _current_version;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  _header._alignment = alignment;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  // The following fields are for sanity checks for whether this archive
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  // will function correctly with this JVM and the bootclasspath it's
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  // invoked with.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  // JVM version string ... changes on each build.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  const char *vm_version = VM_Version::internal_vm_info_string();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  if (strlen(vm_version) < (JVM_IDENT_MAX-1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    strcpy(_header._jvm_ident, vm_version);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
    fail_stop("JVM Ident field for shared archive is too long"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
              " - truncated to <%s>", _header._jvm_ident);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  // Build checks on classpath and jar files
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  _header._num_jars = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  for ( ; cpe != NULL; cpe = cpe->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
    if (cpe->is_jar_file()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
      if (_header._num_jars >= JVM_SHARED_JARS_MAX) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
        fail_stop("Too many jar files to share.", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
      // Jar file - record timestamp and file size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
      struct stat st;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
      const char *path = cpe->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
      if (os::stat(path, &st) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
        // If we can't access a jar file in the boot path, then we can't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
        // make assumptions about where classes get loaded from.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
        fail_stop("Unable to open jar file %s.", path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
      _header._jar[_header._num_jars]._timestamp = st.st_mtime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
      _header._jar[_header._num_jars]._filesize = st.st_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
      _header._num_jars++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
      // If directories appear in boot classpath, they must be empty to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
      // avoid having to verify each individual class file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
      const char* name = ((ClassPathDirEntry*)cpe)->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
      if (!os::dir_is_empty(name)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
        fail_stop("Boot classpath directory %s is not empty.", name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
// Read the FileMapInfo information from the file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
bool FileMapInfo::init_from_file(int fd) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  size_t n = read(fd, &_header, sizeof(struct FileMapHeader));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  if (n != sizeof(struct FileMapHeader)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
    fail_continue("Unable to read the file header.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  if (_header._version != current_version()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
    fail_continue("The shared archive file has the wrong version.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  _file_offset = (long)n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
// Read the FileMapInfo information from the file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
bool FileMapInfo::open_for_read() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  _full_path = Arguments::GetSharedArchivePath();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  int fd = open(_full_path, O_RDONLY | O_BINARY, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  if (fd < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
    if (errno == ENOENT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
      // Not locating the shared archive is ok.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
      fail_continue("Specified shared archive not found.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
      fail_continue("Failed to open shared archive file (%s).",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
                    strerror(errno));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  _fd = fd;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  _file_open = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
// Write the FileMapInfo information to the file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
void FileMapInfo::open_for_write() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
 _full_path = Arguments::GetSharedArchivePath();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  if (PrintSharedSpaces) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    tty->print_cr("Dumping shared data to file: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
    tty->print_cr("   %s", _full_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  // Remove the existing file in case another process has it open.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  remove(_full_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
  if (fd < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    fail_stop("Unable to create shared archive file %s.", _full_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  _fd = fd;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  _file_offset = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  _file_open = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
// Write the header to the file, seek to the next allocation boundary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
void FileMapInfo::write_header() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  write_bytes_aligned(&_header, sizeof(FileMapHeader));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
// Dump shared spaces to file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
void FileMapInfo::write_space(int i, CompactibleSpace* space, bool read_only) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  align_file_position();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  write_region(i, (char*)space->bottom(), space->used(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
               space->capacity(), read_only, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
// Dump region to file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
void FileMapInfo::write_region(int region, char* base, size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
                               size_t capacity, bool read_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
                               bool allow_exec) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[region];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  if (_file_open) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
    guarantee(si->_file_offset == _file_offset, "file offset mismatch.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
    if (PrintSharedSpaces) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
      tty->print_cr("Shared file region %d: 0x%x bytes, addr 0x%x,"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
                    " file offset 0x%x", region, size, base, _file_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
    si->_file_offset = _file_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  si->_base = base;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  si->_used = size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  si->_capacity = capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  si->_read_only = read_only;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
  si->_allow_exec = allow_exec;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  write_bytes_aligned(base, (int)size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
// Dump bytes to file -- at the current file position.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
void FileMapInfo::write_bytes(const void* buffer, int nbytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  if (_file_open) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
    int n = ::write(_fd, buffer, nbytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
    if (n != nbytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
      // It is dangerous to leave the corrupted shared archive file around,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
      // close and remove the file. See bug 6372906.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
      close();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
      remove(_full_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
      fail_stop("Unable to write to shared archive file.", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  _file_offset += nbytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
// Align file position to an allocation unit boundary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
void FileMapInfo::align_file_position() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  long new_file_offset = align_size_up(_file_offset, os::vm_allocation_granularity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  if (new_file_offset != _file_offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
    _file_offset = new_file_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
    if (_file_open) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
      // Seek one byte back from the target and write a byte to insure
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
      // that the written file is the correct length.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
      _file_offset -= 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
      if (lseek(_fd, _file_offset, SEEK_SET) < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
        fail_stop("Unable to seek.", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
      char zero = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
      write_bytes(&zero, 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
// Dump bytes to file -- at the current file position.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
void FileMapInfo::write_bytes_aligned(const void* buffer, int nbytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  align_file_position();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  write_bytes(buffer, nbytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  align_file_position();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
// Close the shared archive file.  This does NOT unmap mapped regions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
void FileMapInfo::close() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  if (_file_open) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
    if (::close(_fd) < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
      fail_stop("Unable to close the shared archive file.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
    _file_open = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
    _fd = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
// Memory map a shared space from the archive file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
bool FileMapInfo::map_space(int i, ReservedSpace rs, ContiguousSpace* space) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
  if (space != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
    if (si->_base != (char*)space->bottom() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
        si->_capacity != space->capacity()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
      fail_continue("Shared space base address does not match.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  bool result = (map_region(i, rs) != NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  if (space != NULL && result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
    space->set_top((HeapWord*)(si->_base + si->_used));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
    space->set_saved_mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
// JVM/TI RedefineClasses() support:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
// Remap the shared readonly space to shared readwrite, private.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
bool FileMapInfo::remap_shared_readonly_as_readwrite() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  if (!si->_read_only) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
    // the space is already readwrite so we are done
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  size_t used = si->_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  size_t size = align_size_up(used, os::vm_allocation_granularity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  if (!open_for_read()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  char *base = os::remap_memory(_fd, _full_path, si->_file_offset,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
                                si->_base, size, false /* !read_only */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
                                si->_allow_exec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  close();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  if (base == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
    fail_continue("Unable to remap shared readonly space (errno=%d).", errno);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  if (base != si->_base) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
    fail_continue("Unable to remap shared readonly space at required address.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  si->_read_only = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
// Memory map a region in the address space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
char* FileMapInfo::map_region(int i, ReservedSpace rs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  size_t used = si->_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  size_t size = align_size_up(used, os::vm_allocation_granularity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
  ReservedSpace mapped_rs = rs.first_part(size, true, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  ReservedSpace unmapped_rs = rs.last_part(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
  mapped_rs.release();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
  return map_region(i, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
// Memory map a region in the address space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
char* FileMapInfo::map_region(int i, bool address_must_match) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
  size_t used = si->_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
  size_t size = align_size_up(used, os::vm_allocation_granularity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
  char *requested_addr = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  if (address_must_match) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
    requested_addr = si->_base;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  char *base = os::map_memory(_fd, _full_path, si->_file_offset,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
                              requested_addr, size, si->_read_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
                              si->_allow_exec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
  if (base == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
    fail_continue("Unable to map shared space.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  if (address_must_match) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
    if (base != si->_base) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
      fail_continue("Unable to map shared space at required address.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
    si->_base = base;          // save mapped address for unmapping.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
  return base;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
// Unmap a memory region in the address space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
void FileMapInfo::unmap_region(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  size_t used = si->_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  size_t size = align_size_up(used, os::vm_allocation_granularity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  if (!os::unmap_memory(si->_base, size)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
    fail_stop("Unable to unmap shared space.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
void FileMapInfo::assert_mark(bool check) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  if (!check) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
    fail_stop("Mark mismatch while restoring from shared file.", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
FileMapInfo* FileMapInfo::_current_info = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
// Open the shared archive file, read and validate the header
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
// information (version, boot classpath, etc.).  If initialization
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
// fails, shared spaces are disabled and the file is closed. [See
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
// fail_continue.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
bool FileMapInfo::initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
  assert(UseSharedSpaces, "UseSharedSpaces expected.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
    fail_continue("Tool agent requires sharing to be disabled.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
  if (!open_for_read()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  init_from_file(_fd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  if (!validate()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
  SharedReadOnlySize =  _header._space[0]._capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  SharedReadWriteSize = _header._space[1]._capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
  SharedMiscDataSize =  _header._space[2]._capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  SharedMiscCodeSize =  _header._space[3]._capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
bool FileMapInfo::validate() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
  if (_header._version != current_version()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
    fail_continue("The shared archive file is the wrong version.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
  if (_header._magic != (int)0xf00baba2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
    fail_continue("The shared archive file has a bad magic number.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  if (strncmp(_header._jvm_ident, VM_Version::internal_vm_info_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
              JVM_IDENT_MAX-1) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
    fail_continue("The shared archive file was created by a different"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
                  " version or build of HotSpot.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  // Cannot verify interpreter yet, as it can only be created after the GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
  // heap has been initialized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  if (_header._num_jars >= JVM_SHARED_JARS_MAX) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
    fail_continue("Too many jar files to share.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  // Build checks on classpath and jar files
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  int num_jars_now = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
  for ( ; cpe != NULL; cpe = cpe->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
    if (cpe->is_jar_file()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
      if (num_jars_now < _header._num_jars) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
        // Jar file - verify timestamp and file size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
        struct stat st;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
        const char *path = cpe->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
        if (os::stat(path, &st) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
          fail_continue("Unable to open jar file %s.", path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
          return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
        if (_header._jar[num_jars_now]._timestamp != st.st_mtime ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
            _header._jar[num_jars_now]._filesize != st.st_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
          fail_continue("A jar file is not the one used while building"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
                        " the shared archive file.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
          return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
      ++num_jars_now;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
      // If directories appear in boot classpath, they must be empty to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
      // avoid having to verify each individual class file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
      const char* name = ((ClassPathDirEntry*)cpe)->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
      if (!os::dir_is_empty(name)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
        fail_continue("Boot classpath directory %s is not empty.", name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
  if (num_jars_now < _header._num_jars) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
    fail_continue("The number of jar files in the boot classpath is"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
                  " less than the number the shared archive was created with.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
// The following method is provided to see whether a given pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
// falls in the mapped shared space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
// Param:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
// p, The given pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
// Return:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
// True if the p is within the mapped shared space, otherwise, false.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
bool FileMapInfo::is_in_shared_space(const void* p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  for (int i = 0; i < CompactingPermGenGen::n_regions; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
    if (p >= _header._space[i]._base &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
        p < _header._space[i]._base + _header._space[i]._used) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
}