Mercurial > hg > truffle
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 |