src/share/vm/memory/filemap.cpp

changeset 4293
fe81517cfb77
parent 4193
716c64bda5ba
child 4396
6c3f47d964f3
     1.1 --- a/src/share/vm/memory/filemap.cpp	Tue Nov 27 07:57:57 2012 -0800
     1.2 +++ b/src/share/vm/memory/filemap.cpp	Wed Nov 28 08:17:59 2012 -0500
     1.3 @@ -25,6 +25,7 @@
     1.4  #include "precompiled.hpp"
     1.5  #include "classfile/classLoader.hpp"
     1.6  #include "classfile/symbolTable.hpp"
     1.7 +#include "classfile/altHashing.hpp"
     1.8  #include "memory/filemap.hpp"
     1.9  #include "runtime/arguments.hpp"
    1.10  #include "runtime/java.hpp"
    1.11 @@ -82,8 +83,37 @@
    1.12    close();
    1.13  }
    1.14  
    1.15 +// Fill in the fileMapInfo structure with data about this VM instance.
    1.16  
    1.17 -// Fill in the fileMapInfo structure with data about this VM instance.
    1.18 +// This method copies the vm version info into header_version.  If the version is too
    1.19 +// long then a truncated version, which has a hash code appended to it, is copied.
    1.20 +//
    1.21 +// Using a template enables this method to verify that header_version is an array of
    1.22 +// length JVM_IDENT_MAX.  This ensures that the code that writes to the CDS file and
    1.23 +// the code that reads the CDS file will both use the same size buffer.  Hence, will
    1.24 +// use identical truncation.  This is necessary for matching of truncated versions.
    1.25 +template <int N> static void get_header_version(char (&header_version) [N]) {
    1.26 +  assert(N == JVM_IDENT_MAX, "Bad header_version size");
    1.27 +
    1.28 +  const char *vm_version = VM_Version::internal_vm_info_string();
    1.29 +  const int version_len = (int)strlen(vm_version);
    1.30 +
    1.31 +  if (version_len < (JVM_IDENT_MAX-1)) {
    1.32 +    strcpy(header_version, vm_version);
    1.33 +
    1.34 +  } else {
    1.35 +    // Get the hash value.  Use a static seed because the hash needs to return the same
    1.36 +    // value over multiple jvm invocations.
    1.37 +    unsigned int hash = AltHashing::murmur3_32(8191, (const jbyte*)vm_version, version_len);
    1.38 +
    1.39 +    // Truncate the ident, saving room for the 8 hex character hash value.
    1.40 +    strncpy(header_version, vm_version, JVM_IDENT_MAX-9);
    1.41 +
    1.42 +    // Append the hash code as eight hex digits.
    1.43 +    sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash);
    1.44 +    header_version[JVM_IDENT_MAX-1] = 0;  // Null terminate.
    1.45 +  }
    1.46 +}
    1.47  
    1.48  void FileMapInfo::populate_header(size_t alignment) {
    1.49    _header._magic = 0xf00baba2;
    1.50 @@ -95,13 +125,7 @@
    1.51    // invoked with.
    1.52  
    1.53    // JVM version string ... changes on each build.
    1.54 -  const char *vm_version = VM_Version::internal_vm_info_string();
    1.55 -  if (strlen(vm_version) < (JVM_IDENT_MAX-1)) {
    1.56 -    strcpy(_header._jvm_ident, vm_version);
    1.57 -  } else {
    1.58 -    fail_stop("JVM Ident field for shared archive is too long"
    1.59 -              " - truncated to <%s>", _header._jvm_ident);
    1.60 -  }
    1.61 +  get_header_version(_header._jvm_ident);
    1.62  
    1.63    // Build checks on classpath and jar files
    1.64    _header._num_jars = 0;
    1.65 @@ -434,8 +458,9 @@
    1.66      fail_continue("The shared archive file has a bad magic number.");
    1.67      return false;
    1.68    }
    1.69 -  if (strncmp(_header._jvm_ident, VM_Version::internal_vm_info_string(),
    1.70 -              JVM_IDENT_MAX-1) != 0) {
    1.71 +  char header_version[JVM_IDENT_MAX];
    1.72 +  get_header_version(header_version);
    1.73 +  if (strncmp(_header._jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
    1.74      fail_continue("The shared archive file was created by a different"
    1.75                    " version or build of HotSpot.");
    1.76      return false;

mercurial