comparison src/share/vm/memory/filemap.cpp @ 7174:fe81517cfb77

6924920: Class Data Sharing limit on the java version string can create failures Summary: Truncate the java version string and add a hash value if it is too long. Reviewed-by: dholmes, coleenp
author hseigel
date Wed, 28 Nov 2012 08:17:59 -0500
parents 716c64bda5ba
children 6c3f47d964f3
comparison
equal deleted inserted replaced
7171:7c15faa95ce7 7174:fe81517cfb77
23 */ 23 */
24 24
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "classfile/classLoader.hpp" 26 #include "classfile/classLoader.hpp"
27 #include "classfile/symbolTable.hpp" 27 #include "classfile/symbolTable.hpp"
28 #include "classfile/altHashing.hpp"
28 #include "memory/filemap.hpp" 29 #include "memory/filemap.hpp"
29 #include "runtime/arguments.hpp" 30 #include "runtime/arguments.hpp"
30 #include "runtime/java.hpp" 31 #include "runtime/java.hpp"
31 #include "runtime/os.hpp" 32 #include "runtime/os.hpp"
32 #include "services/memTracker.hpp" 33 #include "services/memTracker.hpp"
80 va_end(ap); 81 va_end(ap);
81 UseSharedSpaces = false; 82 UseSharedSpaces = false;
82 close(); 83 close();
83 } 84 }
84 85
85
86 // Fill in the fileMapInfo structure with data about this VM instance. 86 // Fill in the fileMapInfo structure with data about this VM instance.
87
88 // This method copies the vm version info into header_version. If the version is too
89 // long then a truncated version, which has a hash code appended to it, is copied.
90 //
91 // Using a template enables this method to verify that header_version is an array of
92 // length JVM_IDENT_MAX. This ensures that the code that writes to the CDS file and
93 // the code that reads the CDS file will both use the same size buffer. Hence, will
94 // use identical truncation. This is necessary for matching of truncated versions.
95 template <int N> static void get_header_version(char (&header_version) [N]) {
96 assert(N == JVM_IDENT_MAX, "Bad header_version size");
97
98 const char *vm_version = VM_Version::internal_vm_info_string();
99 const int version_len = (int)strlen(vm_version);
100
101 if (version_len < (JVM_IDENT_MAX-1)) {
102 strcpy(header_version, vm_version);
103
104 } else {
105 // Get the hash value. Use a static seed because the hash needs to return the same
106 // value over multiple jvm invocations.
107 unsigned int hash = AltHashing::murmur3_32(8191, (const jbyte*)vm_version, version_len);
108
109 // Truncate the ident, saving room for the 8 hex character hash value.
110 strncpy(header_version, vm_version, JVM_IDENT_MAX-9);
111
112 // Append the hash code as eight hex digits.
113 sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash);
114 header_version[JVM_IDENT_MAX-1] = 0; // Null terminate.
115 }
116 }
87 117
88 void FileMapInfo::populate_header(size_t alignment) { 118 void FileMapInfo::populate_header(size_t alignment) {
89 _header._magic = 0xf00baba2; 119 _header._magic = 0xf00baba2;
90 _header._version = _current_version; 120 _header._version = _current_version;
91 _header._alignment = alignment; 121 _header._alignment = alignment;
93 // The following fields are for sanity checks for whether this archive 123 // The following fields are for sanity checks for whether this archive
94 // will function correctly with this JVM and the bootclasspath it's 124 // will function correctly with this JVM and the bootclasspath it's
95 // invoked with. 125 // invoked with.
96 126
97 // JVM version string ... changes on each build. 127 // JVM version string ... changes on each build.
98 const char *vm_version = VM_Version::internal_vm_info_string(); 128 get_header_version(_header._jvm_ident);
99 if (strlen(vm_version) < (JVM_IDENT_MAX-1)) {
100 strcpy(_header._jvm_ident, vm_version);
101 } else {
102 fail_stop("JVM Ident field for shared archive is too long"
103 " - truncated to <%s>", _header._jvm_ident);
104 }
105 129
106 // Build checks on classpath and jar files 130 // Build checks on classpath and jar files
107 _header._num_jars = 0; 131 _header._num_jars = 0;
108 ClassPathEntry *cpe = ClassLoader::classpath_entry(0); 132 ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
109 for ( ; cpe != NULL; cpe = cpe->next()) { 133 for ( ; cpe != NULL; cpe = cpe->next()) {
432 } 456 }
433 if (_header._magic != (int)0xf00baba2) { 457 if (_header._magic != (int)0xf00baba2) {
434 fail_continue("The shared archive file has a bad magic number."); 458 fail_continue("The shared archive file has a bad magic number.");
435 return false; 459 return false;
436 } 460 }
437 if (strncmp(_header._jvm_ident, VM_Version::internal_vm_info_string(), 461 char header_version[JVM_IDENT_MAX];
438 JVM_IDENT_MAX-1) != 0) { 462 get_header_version(header_version);
463 if (strncmp(_header._jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
439 fail_continue("The shared archive file was created by a different" 464 fail_continue("The shared archive file was created by a different"
440 " version or build of HotSpot."); 465 " version or build of HotSpot.");
441 return false; 466 return false;
442 } 467 }
443 468