hotspot/src/share/vm/memory/filemap.cpp
author coleenp
Wed, 20 Mar 2013 08:04:54 -0400
changeset 16430 882cddc35bec
parent 15461 e3acbfdabafa
child 17109 90e6c31bbbe4
permissions -rw-r--r--
8008217: CDS: Class data sharing limits the malloc heap on Solaris Summary: In 64bit VM move CDS archive address to 32G on all platforms using new flag SharedBaseAddress. In 32bit VM set CDS archive address to 3Gb on Linux and let other OSs pick the address. Reviewed-by: kvn, dcubed, zgu, hseigel
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
15461
e3acbfdabafa 7197672: There are issues with shared data on windows
hseigel
parents: 15101
diff changeset
     2
 * Copyright (c) 2003, 2013, 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"
14577
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    28
#include "classfile/altHashing.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    29
#include "memory/filemap.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    30
#include "runtime/arguments.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    31
#include "runtime/java.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    32
#include "runtime/os.hpp"
14120
7d298141c258 7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents: 13728
diff changeset
    33
#include "services/memTracker.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    34
#include "utilities/defaultStream.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    35
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
# include <sys/stat.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
# include <errno.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
#ifndef O_BINARY       // if defined (Win32) use binary files.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
#define O_BINARY 0     // otherwise do nothing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
extern address JVM_FunctionAtStart();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
extern address JVM_FunctionAtEnd();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1
diff changeset
    47
// Complain and stop. All error conditions occurring during the writing of
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
// an archive file should stop the process.  Unrecoverable errors during
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
// the reading of the archive file should stop the process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
static void fail(const char *msg, va_list ap) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  // This occurs very early during initialization: tty is not initialized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
  jio_fprintf(defaultStream::error_stream(),
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1
diff changeset
    54
              "An error has occurred while processing the"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
              " shared archive file.\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  jio_vfprintf(defaultStream::error_stream(), msg, ap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  jio_fprintf(defaultStream::error_stream(), "\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  vm_exit_during_initialization("Unable to use shared archive.", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
void FileMapInfo::fail_stop(const char *msg, ...) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
        va_list ap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  va_start(ap, msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  fail(msg, ap);        // Never returns.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
  va_end(ap);           // for completeness.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
// Complain and continue.  Recoverable errors during the reading of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
// archive file may continue (with sharing disabled).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
// If we continue, then disable shared spaces and close the file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
void FileMapInfo::fail_continue(const char *msg, ...) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  va_list ap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  va_start(ap, msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  if (RequireSharedSpaces) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
    fail(msg, ap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  va_end(ap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  UseSharedSpaces = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  close();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
14577
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    86
// Fill in the fileMapInfo structure with data about this VM instance.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
14577
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    88
// This method copies the vm version info into header_version.  If the version is too
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    89
// long then a truncated version, which has a hash code appended to it, is copied.
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    90
//
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    91
// Using a template enables this method to verify that header_version is an array of
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    92
// length JVM_IDENT_MAX.  This ensures that the code that writes to the CDS file and
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    93
// the code that reads the CDS file will both use the same size buffer.  Hence, will
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    94
// use identical truncation.  This is necessary for matching of truncated versions.
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    95
template <int N> static void get_header_version(char (&header_version) [N]) {
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    96
  assert(N == JVM_IDENT_MAX, "Bad header_version size");
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    97
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    98
  const char *vm_version = VM_Version::internal_vm_info_string();
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
    99
  const int version_len = (int)strlen(vm_version);
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   100
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   101
  if (version_len < (JVM_IDENT_MAX-1)) {
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   102
    strcpy(header_version, vm_version);
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   103
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   104
  } else {
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   105
    // Get the hash value.  Use a static seed because the hash needs to return the same
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   106
    // value over multiple jvm invocations.
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   107
    unsigned int hash = AltHashing::murmur3_32(8191, (const jbyte*)vm_version, version_len);
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   108
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   109
    // Truncate the ident, saving room for the 8 hex character hash value.
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   110
    strncpy(header_version, vm_version, JVM_IDENT_MAX-9);
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   111
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   112
    // Append the hash code as eight hex digits.
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   113
    sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash);
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   114
    header_version[JVM_IDENT_MAX-1] = 0;  // Null terminate.
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   115
  }
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   116
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
void FileMapInfo::populate_header(size_t alignment) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  _header._magic = 0xf00baba2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  _header._version = _current_version;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  _header._alignment = alignment;
15101
58d43bf04c45 8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents: 15100
diff changeset
   122
  _header._obj_alignment = ObjectAlignmentInBytes;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  // The following fields are for sanity checks for whether this archive
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  // will function correctly with this JVM and the bootclasspath it's
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  // invoked with.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  // JVM version string ... changes on each build.
14577
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   129
  get_header_version(_header._jvm_ident);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  // Build checks on classpath and jar files
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  _header._num_jars = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  for ( ; cpe != NULL; cpe = cpe->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
    if (cpe->is_jar_file()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
      if (_header._num_jars >= JVM_SHARED_JARS_MAX) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
        fail_stop("Too many jar files to share.", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
      // Jar file - record timestamp and file size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
      struct stat st;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
      const char *path = cpe->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
      if (os::stat(path, &st) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
        // If we can't access a jar file in the boot path, then we can't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
        // make assumptions about where classes get loaded from.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
        fail_stop("Unable to open jar file %s.", path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
      _header._jar[_header._num_jars]._timestamp = st.st_mtime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
      _header._jar[_header._num_jars]._filesize = st.st_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
      _header._num_jars++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
      // If directories appear in boot classpath, they must be empty to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
      // avoid having to verify each individual class file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
      const char* name = ((ClassPathDirEntry*)cpe)->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
      if (!os::dir_is_empty(name)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
        fail_stop("Boot classpath directory %s is not empty.", name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
// Read the FileMapInfo information from the file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
bool FileMapInfo::init_from_file(int fd) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  size_t n = read(fd, &_header, sizeof(struct FileMapHeader));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  if (n != sizeof(struct FileMapHeader)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
    fail_continue("Unable to read the file header.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  if (_header._version != current_version()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    fail_continue("The shared archive file has the wrong version.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  _file_offset = (long)n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
// Read the FileMapInfo information from the file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
bool FileMapInfo::open_for_read() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  _full_path = Arguments::GetSharedArchivePath();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  int fd = open(_full_path, O_RDONLY | O_BINARY, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  if (fd < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
    if (errno == ENOENT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
      // Not locating the shared archive is ok.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
      fail_continue("Specified shared archive not found.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
      fail_continue("Failed to open shared archive file (%s).",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
                    strerror(errno));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  _fd = fd;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  _file_open = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
// Write the FileMapInfo information to the file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
void FileMapInfo::open_for_write() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
 _full_path = Arguments::GetSharedArchivePath();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  if (PrintSharedSpaces) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    tty->print_cr("Dumping shared data to file: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
    tty->print_cr("   %s", _full_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
15461
e3acbfdabafa 7197672: There are issues with shared data on windows
hseigel
parents: 15101
diff changeset
   213
#ifdef _WINDOWS  // On Windows, need WRITE permission to remove the file.
e3acbfdabafa 7197672: There are issues with shared data on windows
hseigel
parents: 15101
diff changeset
   214
  chmod(_full_path, _S_IREAD | _S_IWRITE);
e3acbfdabafa 7197672: There are issues with shared data on windows
hseigel
parents: 15101
diff changeset
   215
#endif
e3acbfdabafa 7197672: There are issues with shared data on windows
hseigel
parents: 15101
diff changeset
   216
e3acbfdabafa 7197672: There are issues with shared data on windows
hseigel
parents: 15101
diff changeset
   217
  // Use remove() to delete the existing file because, on Unix, this will
e3acbfdabafa 7197672: There are issues with shared data on windows
hseigel
parents: 15101
diff changeset
   218
  // allow processes that have it open continued access to the file.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  remove(_full_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  if (fd < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
    fail_stop("Unable to create shared archive file %s.", _full_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  _fd = fd;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  _file_offset = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  _file_open = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
// Write the header to the file, seek to the next allocation boundary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
void FileMapInfo::write_header() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  write_bytes_aligned(&_header, sizeof(FileMapHeader));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
// Dump shared spaces to file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   239
void FileMapInfo::write_space(int i, Metaspace* space, bool read_only) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  align_file_position();
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   241
  size_t used = space->used_words(Metaspace::NonClassType) * BytesPerWord;
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   242
  size_t capacity = space->capacity_words(Metaspace::NonClassType) * BytesPerWord;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   244
  write_region(i, (char*)space->bottom(), used, capacity, read_only, false);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
// Dump region to file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
void FileMapInfo::write_region(int region, char* base, size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
                               size_t capacity, bool read_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
                               bool allow_exec) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[region];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  if (_file_open) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
    guarantee(si->_file_offset == _file_offset, "file offset mismatch.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
    if (PrintSharedSpaces) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   258
      tty->print_cr("Shared file region %d: 0x%6x bytes, addr " INTPTR_FORMAT
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   259
                    " file offset 0x%6x", region, size, base, _file_offset);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
    si->_file_offset = _file_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  si->_base = base;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  si->_used = size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  si->_capacity = capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
  si->_read_only = read_only;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  si->_allow_exec = allow_exec;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  write_bytes_aligned(base, (int)size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
// Dump bytes to file -- at the current file position.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
void FileMapInfo::write_bytes(const void* buffer, int nbytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  if (_file_open) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
    int n = ::write(_fd, buffer, nbytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
    if (n != nbytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
      // It is dangerous to leave the corrupted shared archive file around,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
      // close and remove the file. See bug 6372906.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
      close();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
      remove(_full_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
      fail_stop("Unable to write to shared archive file.", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  _file_offset += nbytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
// Align file position to an allocation unit boundary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
void FileMapInfo::align_file_position() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  long new_file_offset = align_size_up(_file_offset, os::vm_allocation_granularity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  if (new_file_offset != _file_offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
    _file_offset = new_file_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
    if (_file_open) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
      // Seek one byte back from the target and write a byte to insure
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
      // that the written file is the correct length.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
      _file_offset -= 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
      if (lseek(_fd, _file_offset, SEEK_SET) < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
        fail_stop("Unable to seek.", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
      char zero = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
      write_bytes(&zero, 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
// Dump bytes to file -- at the current file position.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
void FileMapInfo::write_bytes_aligned(const void* buffer, int nbytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
  align_file_position();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
  write_bytes(buffer, nbytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
  align_file_position();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
// Close the shared archive file.  This does NOT unmap mapped regions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
void FileMapInfo::close() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
  if (_file_open) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
    if (::close(_fd) < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
      fail_stop("Unable to close the shared archive file.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
    _file_open = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
    _fd = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
// JVM/TI RedefineClasses() support:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
// Remap the shared readonly space to shared readwrite, private.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
bool FileMapInfo::remap_shared_readonly_as_readwrite() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  if (!si->_read_only) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
    // the space is already readwrite so we are done
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  size_t used = si->_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  size_t size = align_size_up(used, os::vm_allocation_granularity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  if (!open_for_read()) {
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
  char *base = os::remap_memory(_fd, _full_path, si->_file_offset,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
                                si->_base, size, false /* !read_only */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
                                si->_allow_exec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
  close();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  if (base == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
    fail_continue("Unable to remap shared readonly space (errno=%d).", errno);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  if (base != si->_base) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
    fail_continue("Unable to remap shared readonly space at required address.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
  si->_read_only = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   361
// Map the whole region at once, assumed to be allocated contiguously.
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   362
ReservedSpace FileMapInfo::reserve_shared_memory() {
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   363
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0];
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   364
  char* requested_addr = si->_base;
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   365
  size_t alignment = os::vm_allocation_granularity();
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   366
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   367
  size_t size = align_size_up(SharedReadOnlySize + SharedReadWriteSize +
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   368
                              SharedMiscDataSize + SharedMiscCodeSize,
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   369
                              alignment);
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   370
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   371
  // Reserve the space first, then map otherwise map will go right over some
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   372
  // other reserved memory (like the code cache).
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   373
  ReservedSpace rs(size, alignment, false, requested_addr);
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   374
  if (!rs.is_reserved()) {
16430
882cddc35bec 8008217: CDS: Class data sharing limits the malloc heap on Solaris
coleenp
parents: 15461
diff changeset
   375
    fail_continue(err_msg("Unable to reserve shared space at required address " INTPTR_FORMAT, requested_addr));
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   376
    return rs;
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   377
  }
14120
7d298141c258 7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents: 13728
diff changeset
   378
  // the reserved virtual memory is for mapping class data sharing archive
15100
0ae85ac7c8b0 8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents: 14577
diff changeset
   379
  MemTracker::record_virtual_memory_type((address)rs.base(), mtClassShared);
0ae85ac7c8b0 8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents: 14577
diff changeset
   380
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   381
  return rs;
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   382
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
// Memory map a region in the address space.
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   385
static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode"};
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   387
char* FileMapInfo::map_region(int i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  size_t used = si->_used;
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   390
  size_t alignment = os::vm_allocation_granularity();
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   391
  size_t size = align_size_up(used, alignment);
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   392
  char *requested_addr = si->_base;
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   393
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   394
  // map the contents of the CDS archive in this memory
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  char *base = os::map_memory(_fd, _full_path, si->_file_offset,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
                              requested_addr, size, si->_read_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
                              si->_allow_exec);
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   398
  if (base == NULL || base != si->_base) {
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   399
    fail_continue(err_msg("Unable to map %s shared space at required address.", shared_region_name[i]));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  }
15100
0ae85ac7c8b0 8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents: 14577
diff changeset
   402
#ifdef _WINDOWS
0ae85ac7c8b0 8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents: 14577
diff changeset
   403
  // This call is Windows-only because the memory_type gets recorded for the other platforms
0ae85ac7c8b0 8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents: 14577
diff changeset
   404
  // in method FileMapInfo::reserve_shared_memory(), which is not called on Windows.
0ae85ac7c8b0 8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents: 14577
diff changeset
   405
  MemTracker::record_virtual_memory_type((address)base, mtClassShared);
0ae85ac7c8b0 8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents: 14577
diff changeset
   406
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  return base;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
// Unmap a memory region in the address space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
void FileMapInfo::unmap_region(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  size_t used = si->_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  size_t size = align_size_up(used, os::vm_allocation_granularity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  if (!os::unmap_memory(si->_base, size)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
    fail_stop("Unable to unmap shared space.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
void FileMapInfo::assert_mark(bool check) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  if (!check) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
    fail_stop("Mark mismatch while restoring from shared file.", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
FileMapInfo* FileMapInfo::_current_info = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
// Open the shared archive file, read and validate the header
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
// information (version, boot classpath, etc.).  If initialization
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
// fails, shared spaces are disabled and the file is closed. [See
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
// fail_continue.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
bool FileMapInfo::initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  assert(UseSharedSpaces, "UseSharedSpaces expected.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
    fail_continue("Tool agent requires sharing to be disabled.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  if (!open_for_read()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  init_from_file(_fd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  if (!validate()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
  SharedReadOnlySize =  _header._space[0]._capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  SharedReadWriteSize = _header._space[1]._capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  SharedMiscDataSize =  _header._space[2]._capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  SharedMiscCodeSize =  _header._space[3]._capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
bool FileMapInfo::validate() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  if (_header._version != current_version()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
    fail_continue("The shared archive file is the wrong version.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  if (_header._magic != (int)0xf00baba2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
    fail_continue("The shared archive file has a bad magic number.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
  }
14577
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   471
  char header_version[JVM_IDENT_MAX];
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   472
  get_header_version(header_version);
fd68d810d86b 6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents: 14120
diff changeset
   473
  if (strncmp(_header._jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
    fail_continue("The shared archive file was created by a different"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
                  " version or build of HotSpot.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
  }
15101
58d43bf04c45 8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents: 15100
diff changeset
   478
  if (_header._obj_alignment != ObjectAlignmentInBytes) {
58d43bf04c45 8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents: 15100
diff changeset
   479
    fail_continue("The shared archive file's ObjectAlignmentInBytes of %d"
58d43bf04c45 8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents: 15100
diff changeset
   480
                  " does not equal the current ObjectAlignmentInBytes of %d.",
58d43bf04c45 8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents: 15100
diff changeset
   481
                  _header._obj_alignment, ObjectAlignmentInBytes);
58d43bf04c45 8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents: 15100
diff changeset
   482
    return false;
58d43bf04c45 8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents: 15100
diff changeset
   483
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
  // Cannot verify interpreter yet, as it can only be created after the GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
  // heap has been initialized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
  if (_header._num_jars >= JVM_SHARED_JARS_MAX) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
    fail_continue("Too many jar files to share.");
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
  // Build checks on classpath and jar files
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
  int num_jars_now = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
  ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
  for ( ; cpe != NULL; cpe = cpe->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
    if (cpe->is_jar_file()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
      if (num_jars_now < _header._num_jars) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
        // Jar file - verify timestamp and file size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
        struct stat st;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
        const char *path = cpe->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
        if (os::stat(path, &st) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
          fail_continue("Unable to open jar file %s.", path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
          return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
        if (_header._jar[num_jars_now]._timestamp != st.st_mtime ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
            _header._jar[num_jars_now]._filesize != st.st_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
          fail_continue("A jar file is not the one used while building"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
                        " the shared archive file.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
          return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
      ++num_jars_now;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
      // If directories appear in boot classpath, they must be empty to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
      // avoid having to verify each individual class file.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
      const char* name = ((ClassPathDirEntry*)cpe)->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
      if (!os::dir_is_empty(name)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
        fail_continue("Boot classpath directory %s is not empty.", name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  if (num_jars_now < _header._num_jars) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
    fail_continue("The number of jar files in the boot classpath is"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
                  " less than the number the shared archive was created with.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
// The following method is provided to see whether a given pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
// falls in the mapped shared space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
// Param:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
// p, The given pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
// Return:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
// True if the p is within the mapped shared space, otherwise, false.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
bool FileMapInfo::is_in_shared_space(const void* p) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 7405
diff changeset
   543
  for (int i = 0; i < MetaspaceShared::n_regions; i++) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
    if (p >= _header._space[i]._base &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
        p < _header._space[i]._base + _header._space[i]._used) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
}