Mercurial > hg > graal-jvmci-8
comparison src/share/vm/memory/filemap.cpp @ 20804:7848fc12602b
Merge with jdk8u40-b25
author | Gilles Duboscq <gilles.m.duboscq@oracle.com> |
---|---|
date | Tue, 07 Apr 2015 14:58:49 +0200 |
parents | 0558eb13dcf3 |
children |
comparison
equal
deleted
inserted
replaced
20184:84105dcdb05b | 20804:7848fc12602b |
---|---|
22 * | 22 * |
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/sharedClassUtil.hpp" | |
27 #include "classfile/symbolTable.hpp" | 28 #include "classfile/symbolTable.hpp" |
29 #include "classfile/systemDictionaryShared.hpp" | |
28 #include "classfile/altHashing.hpp" | 30 #include "classfile/altHashing.hpp" |
29 #include "memory/filemap.hpp" | 31 #include "memory/filemap.hpp" |
32 #include "memory/metadataFactory.hpp" | |
33 #include "memory/oopFactory.hpp" | |
34 #include "oops/objArrayOop.hpp" | |
30 #include "runtime/arguments.hpp" | 35 #include "runtime/arguments.hpp" |
31 #include "runtime/java.hpp" | 36 #include "runtime/java.hpp" |
32 #include "runtime/os.hpp" | 37 #include "runtime/os.hpp" |
33 #include "services/memTracker.hpp" | 38 #include "services/memTracker.hpp" |
34 #include "utilities/defaultStream.hpp" | 39 #include "utilities/defaultStream.hpp" |
39 #ifndef O_BINARY // if defined (Win32) use binary files. | 44 #ifndef O_BINARY // if defined (Win32) use binary files. |
40 #define O_BINARY 0 // otherwise do nothing. | 45 #define O_BINARY 0 // otherwise do nothing. |
41 #endif | 46 #endif |
42 | 47 |
43 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC | 48 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC |
44 | |
45 extern address JVM_FunctionAtStart(); | 49 extern address JVM_FunctionAtStart(); |
46 extern address JVM_FunctionAtEnd(); | 50 extern address JVM_FunctionAtEnd(); |
47 | 51 |
48 // Complain and stop. All error conditions occurring during the writing of | 52 // Complain and stop. All error conditions occurring during the writing of |
49 // an archive file should stop the process. Unrecoverable errors during | 53 // an archive file should stop the process. Unrecoverable errors during |
75 // If we continue, then disable shared spaces and close the file. | 79 // If we continue, then disable shared spaces and close the file. |
76 | 80 |
77 void FileMapInfo::fail_continue(const char *msg, ...) { | 81 void FileMapInfo::fail_continue(const char *msg, ...) { |
78 va_list ap; | 82 va_list ap; |
79 va_start(ap, msg); | 83 va_start(ap, msg); |
80 if (RequireSharedSpaces) { | 84 MetaspaceShared::set_archive_loading_failed(); |
81 fail(msg, ap); | 85 if (PrintSharedArchiveAndExit && _validating_classpath_entry_table) { |
86 // If we are doing PrintSharedArchiveAndExit and some of the classpath entries | |
87 // do not validate, we can still continue "limping" to validate the remaining | |
88 // entries. No need to quit. | |
89 tty->print("["); | |
90 tty->vprint(msg, ap); | |
91 tty->print_cr("]"); | |
92 } else { | |
93 if (RequireSharedSpaces) { | |
94 fail(msg, ap); | |
95 } else { | |
96 if (PrintSharedSpaces) { | |
97 tty->print_cr("UseSharedSpaces: %s", msg); | |
98 } | |
99 } | |
100 UseSharedSpaces = false; | |
101 assert(current_info() != NULL, "singleton must be registered"); | |
102 current_info()->close(); | |
82 } | 103 } |
83 va_end(ap); | 104 va_end(ap); |
84 UseSharedSpaces = false; | |
85 close(); | |
86 } | 105 } |
87 | 106 |
88 // Fill in the fileMapInfo structure with data about this VM instance. | 107 // Fill in the fileMapInfo structure with data about this VM instance. |
89 | 108 |
90 // This method copies the vm version info into header_version. If the version is too | 109 // This method copies the vm version info into header_version. If the version is too |
115 sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash); | 134 sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash); |
116 header_version[JVM_IDENT_MAX-1] = 0; // Null terminate. | 135 header_version[JVM_IDENT_MAX-1] = 0; // Null terminate. |
117 } | 136 } |
118 } | 137 } |
119 | 138 |
139 FileMapInfo::FileMapInfo() { | |
140 assert(_current_info == NULL, "must be singleton"); // not thread safe | |
141 _current_info = this; | |
142 memset(this, 0, sizeof(FileMapInfo)); | |
143 _file_offset = 0; | |
144 _file_open = false; | |
145 _header = SharedClassUtil::allocate_file_map_header(); | |
146 _header->_version = _invalid_version; | |
147 } | |
148 | |
149 FileMapInfo::~FileMapInfo() { | |
150 assert(_current_info == this, "must be singleton"); // not thread safe | |
151 _current_info = NULL; | |
152 } | |
153 | |
120 void FileMapInfo::populate_header(size_t alignment) { | 154 void FileMapInfo::populate_header(size_t alignment) { |
121 _header._magic = 0xf00baba2; | 155 _header->populate(this, alignment); |
122 _header._version = _current_version; | 156 } |
123 _header._alignment = alignment; | 157 |
124 _header._obj_alignment = ObjectAlignmentInBytes; | 158 size_t FileMapInfo::FileMapHeader::data_size() { |
159 return SharedClassUtil::file_map_header_size() - sizeof(FileMapInfo::FileMapHeaderBase); | |
160 } | |
161 | |
162 void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) { | |
163 _magic = 0xf00baba2; | |
164 _version = _current_version; | |
165 _alignment = alignment; | |
166 _obj_alignment = ObjectAlignmentInBytes; | |
167 _classpath_entry_table_size = mapinfo->_classpath_entry_table_size; | |
168 _classpath_entry_table = mapinfo->_classpath_entry_table; | |
169 _classpath_entry_size = mapinfo->_classpath_entry_size; | |
125 | 170 |
126 // The following fields are for sanity checks for whether this archive | 171 // The following fields are for sanity checks for whether this archive |
127 // will function correctly with this JVM and the bootclasspath it's | 172 // will function correctly with this JVM and the bootclasspath it's |
128 // invoked with. | 173 // invoked with. |
129 | 174 |
130 // JVM version string ... changes on each build. | 175 // JVM version string ... changes on each build. |
131 get_header_version(_header._jvm_ident); | 176 get_header_version(_jvm_ident); |
132 | 177 } |
133 // Build checks on classpath and jar files | 178 |
134 _header._num_jars = 0; | 179 void FileMapInfo::allocate_classpath_entry_table() { |
135 ClassPathEntry *cpe = ClassLoader::classpath_entry(0); | 180 int bytes = 0; |
136 for ( ; cpe != NULL; cpe = cpe->next()) { | 181 int count = 0; |
137 | 182 char* strptr = NULL; |
138 if (cpe->is_jar_file()) { | 183 char* strptr_max = NULL; |
139 if (_header._num_jars >= JVM_SHARED_JARS_MAX) { | 184 Thread* THREAD = Thread::current(); |
140 fail_stop("Too many jar files to share.", NULL); | 185 |
186 ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); | |
187 size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); | |
188 | |
189 for (int pass=0; pass<2; pass++) { | |
190 ClassPathEntry *cpe = ClassLoader::classpath_entry(0); | |
191 | |
192 for (int cur_entry = 0 ; cpe != NULL; cpe = cpe->next(), cur_entry++) { | |
193 const char *name = cpe->name(); | |
194 int name_bytes = (int)(strlen(name) + 1); | |
195 | |
196 if (pass == 0) { | |
197 count ++; | |
198 bytes += (int)entry_size; | |
199 bytes += name_bytes; | |
200 if (TraceClassPaths || (TraceClassLoading && Verbose)) { | |
201 tty->print_cr("[Add main shared path (%s) %s]", (cpe->is_jar_file() ? "jar" : "dir"), name); | |
202 } | |
203 } else { | |
204 SharedClassPathEntry* ent = shared_classpath(cur_entry); | |
205 if (cpe->is_jar_file()) { | |
206 struct stat st; | |
207 if (os::stat(name, &st) != 0) { | |
208 // The file/dir must exist, or it would not have been added | |
209 // into ClassLoader::classpath_entry(). | |
210 // | |
211 // If we can't access a jar file in the boot path, then we can't | |
212 // make assumptions about where classes get loaded from. | |
213 FileMapInfo::fail_stop("Unable to open jar file %s.", name); | |
214 } | |
215 | |
216 EXCEPTION_MARK; // The following call should never throw, but would exit VM on error. | |
217 SharedClassUtil::update_shared_classpath(cpe, ent, st.st_mtime, st.st_size, THREAD); | |
218 } else { | |
219 ent->_filesize = -1; | |
220 if (!os::dir_is_empty(name)) { | |
221 ClassLoader::exit_with_path_failure("Cannot have non-empty directory in archived classpaths", name); | |
222 } | |
223 } | |
224 ent->_name = strptr; | |
225 if (strptr + name_bytes <= strptr_max) { | |
226 strncpy(strptr, name, (size_t)name_bytes); // name_bytes includes trailing 0. | |
227 strptr += name_bytes; | |
228 } else { | |
229 assert(0, "miscalculated buffer size"); | |
230 } | |
141 } | 231 } |
142 | 232 } |
143 // Jar file - record timestamp and file size. | 233 |
144 struct stat st; | 234 if (pass == 0) { |
145 const char *path = cpe->name(); | 235 EXCEPTION_MARK; // The following call should never throw, but would exit VM on error. |
146 if (os::stat(path, &st) != 0) { | 236 Array<u8>* arr = MetadataFactory::new_array<u8>(loader_data, (bytes + 7)/8, THREAD); |
147 // If we can't access a jar file in the boot path, then we can't | 237 strptr = (char*)(arr->data()); |
148 // make assumptions about where classes get loaded from. | 238 strptr_max = strptr + bytes; |
149 fail_stop("Unable to open jar file %s.", path); | 239 SharedClassPathEntry* table = (SharedClassPathEntry*)strptr; |
240 strptr += entry_size * count; | |
241 | |
242 _classpath_entry_table_size = count; | |
243 _classpath_entry_table = table; | |
244 _classpath_entry_size = entry_size; | |
245 } | |
246 } | |
247 } | |
248 | |
249 bool FileMapInfo::validate_classpath_entry_table() { | |
250 _validating_classpath_entry_table = true; | |
251 | |
252 int count = _header->_classpath_entry_table_size; | |
253 | |
254 _classpath_entry_table = _header->_classpath_entry_table; | |
255 _classpath_entry_size = _header->_classpath_entry_size; | |
256 | |
257 for (int i=0; i<count; i++) { | |
258 SharedClassPathEntry* ent = shared_classpath(i); | |
259 struct stat st; | |
260 const char* name = ent->_name; | |
261 bool ok = true; | |
262 if (TraceClassPaths || (TraceClassLoading && Verbose)) { | |
263 tty->print_cr("[Checking shared classpath entry: %s]", name); | |
264 } | |
265 if (os::stat(name, &st) != 0) { | |
266 fail_continue("Required classpath entry does not exist: %s", name); | |
267 ok = false; | |
268 } else if (ent->is_dir()) { | |
269 if (!os::dir_is_empty(name)) { | |
270 fail_continue("directory is not empty: %s", name); | |
271 ok = false; | |
150 } | 272 } |
151 _header._jar[_header._num_jars]._timestamp = st.st_mtime; | |
152 _header._jar[_header._num_jars]._filesize = st.st_size; | |
153 _header._num_jars++; | |
154 } else { | 273 } else { |
155 | 274 if (ent->_timestamp != st.st_mtime || |
156 // If directories appear in boot classpath, they must be empty to | 275 ent->_filesize != st.st_size) { |
157 // avoid having to verify each individual class file. | 276 ok = false; |
158 const char* name = ((ClassPathDirEntry*)cpe)->name(); | 277 if (PrintSharedArchiveAndExit) { |
159 if (!os::dir_is_empty(name)) { | 278 fail_continue(ent->_timestamp != st.st_mtime ? |
160 fail_stop("Boot classpath directory %s is not empty.", name); | 279 "Timestamp mismatch" : |
280 "File size mismatch"); | |
281 } else { | |
282 fail_continue("A jar file is not the one used while building" | |
283 " the shared archive file: %s", name); | |
284 } | |
161 } | 285 } |
162 } | 286 } |
163 } | 287 if (ok) { |
288 if (TraceClassPaths || (TraceClassLoading && Verbose)) { | |
289 tty->print_cr("[ok]"); | |
290 } | |
291 } else if (!PrintSharedArchiveAndExit) { | |
292 _validating_classpath_entry_table = false; | |
293 return false; | |
294 } | |
295 } | |
296 | |
297 _classpath_entry_table_size = _header->_classpath_entry_table_size; | |
298 _validating_classpath_entry_table = false; | |
299 return true; | |
164 } | 300 } |
165 | 301 |
166 | 302 |
167 // Read the FileMapInfo information from the file. | 303 // Read the FileMapInfo information from the file. |
168 | 304 |
169 bool FileMapInfo::init_from_file(int fd) { | 305 bool FileMapInfo::init_from_file(int fd) { |
170 | 306 size_t sz = _header->data_size(); |
171 size_t n = read(fd, &_header, sizeof(struct FileMapHeader)); | 307 char* addr = _header->data(); |
172 if (n != sizeof(struct FileMapHeader)) { | 308 size_t n = os::read(fd, addr, (unsigned int)sz); |
309 if (n != sz) { | |
173 fail_continue("Unable to read the file header."); | 310 fail_continue("Unable to read the file header."); |
174 return false; | 311 return false; |
175 } | 312 } |
176 if (_header._version != current_version()) { | 313 if (_header->_version != current_version()) { |
177 fail_continue("The shared archive file has the wrong version."); | 314 fail_continue("The shared archive file has the wrong version."); |
178 return false; | 315 return false; |
179 } | 316 } |
317 | |
318 size_t info_size = _header->_paths_misc_info_size; | |
319 _paths_misc_info = NEW_C_HEAP_ARRAY_RETURN_NULL(char, info_size, mtClass); | |
320 if (_paths_misc_info == NULL) { | |
321 fail_continue("Unable to read the file header."); | |
322 return false; | |
323 } | |
324 n = os::read(fd, _paths_misc_info, (unsigned int)info_size); | |
325 if (n != info_size) { | |
326 fail_continue("Unable to read the shared path info header."); | |
327 FREE_C_HEAP_ARRAY(char, _paths_misc_info, mtClass); | |
328 _paths_misc_info = NULL; | |
329 return false; | |
330 } | |
331 | |
180 size_t len = lseek(fd, 0, SEEK_END); | 332 size_t len = lseek(fd, 0, SEEK_END); |
181 struct FileMapInfo::FileMapHeader::space_info* si = | 333 struct FileMapInfo::FileMapHeader::space_info* si = |
182 &_header._space[MetaspaceShared::mc]; | 334 &_header->_space[MetaspaceShared::mc]; |
183 if (si->_file_offset >= len || len - si->_file_offset < si->_used) { | 335 if (si->_file_offset >= len || len - si->_file_offset < si->_used) { |
184 fail_continue("The shared archive file has been truncated."); | 336 fail_continue("The shared archive file has been truncated."); |
185 return false; | 337 return false; |
186 } | 338 } |
187 _file_offset = n; | 339 |
340 _file_offset += (long)n; | |
188 return true; | 341 return true; |
189 } | 342 } |
190 | 343 |
191 | 344 |
192 // Read the FileMapInfo information from the file. | 345 // Read the FileMapInfo information from the file. |
237 | 390 |
238 | 391 |
239 // Write the header to the file, seek to the next allocation boundary. | 392 // Write the header to the file, seek to the next allocation boundary. |
240 | 393 |
241 void FileMapInfo::write_header() { | 394 void FileMapInfo::write_header() { |
242 write_bytes_aligned(&_header, sizeof(FileMapHeader)); | 395 int info_size = ClassLoader::get_shared_paths_misc_info_size(); |
396 | |
397 _header->_paths_misc_info_size = info_size; | |
398 | |
399 align_file_position(); | |
400 size_t sz = _header->data_size(); | |
401 char* addr = _header->data(); | |
402 write_bytes(addr, (int)sz); // skip the C++ vtable | |
403 write_bytes(ClassLoader::get_shared_paths_misc_info(), info_size); | |
404 align_file_position(); | |
243 } | 405 } |
244 | 406 |
245 | 407 |
246 // Dump shared spaces to file. | 408 // Dump shared spaces to file. |
247 | 409 |
248 void FileMapInfo::write_space(int i, Metaspace* space, bool read_only) { | 410 void FileMapInfo::write_space(int i, Metaspace* space, bool read_only) { |
249 align_file_position(); | 411 align_file_position(); |
250 size_t used = space->used_bytes_slow(Metaspace::NonClassType); | 412 size_t used = space->used_bytes_slow(Metaspace::NonClassType); |
251 size_t capacity = space->capacity_bytes_slow(Metaspace::NonClassType); | 413 size_t capacity = space->capacity_bytes_slow(Metaspace::NonClassType); |
252 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; | 414 struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i]; |
253 write_region(i, (char*)space->bottom(), used, capacity, read_only, false); | 415 write_region(i, (char*)space->bottom(), used, capacity, read_only, false); |
254 } | 416 } |
255 | 417 |
256 | 418 |
257 // Dump region to file. | 419 // Dump region to file. |
258 | 420 |
259 void FileMapInfo::write_region(int region, char* base, size_t size, | 421 void FileMapInfo::write_region(int region, char* base, size_t size, |
260 size_t capacity, bool read_only, | 422 size_t capacity, bool read_only, |
261 bool allow_exec) { | 423 bool allow_exec) { |
262 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[region]; | 424 struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[region]; |
263 | 425 |
264 if (_file_open) { | 426 if (_file_open) { |
265 guarantee(si->_file_offset == _file_offset, "file offset mismatch."); | 427 guarantee(si->_file_offset == _file_offset, "file offset mismatch."); |
266 if (PrintSharedSpaces) { | 428 if (PrintSharedSpaces) { |
267 tty->print_cr("Shared file region %d: 0x%6x bytes, addr " INTPTR_FORMAT | 429 tty->print_cr("Shared file region %d: 0x%6x bytes, addr " INTPTR_FORMAT |
341 | 503 |
342 | 504 |
343 // JVM/TI RedefineClasses() support: | 505 // JVM/TI RedefineClasses() support: |
344 // Remap the shared readonly space to shared readwrite, private. | 506 // Remap the shared readonly space to shared readwrite, private. |
345 bool FileMapInfo::remap_shared_readonly_as_readwrite() { | 507 bool FileMapInfo::remap_shared_readonly_as_readwrite() { |
346 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0]; | 508 struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[0]; |
347 if (!si->_read_only) { | 509 if (!si->_read_only) { |
348 // the space is already readwrite so we are done | 510 // the space is already readwrite so we are done |
349 return true; | 511 return true; |
350 } | 512 } |
351 size_t used = si->_used; | 513 size_t used = si->_used; |
369 return true; | 531 return true; |
370 } | 532 } |
371 | 533 |
372 // Map the whole region at once, assumed to be allocated contiguously. | 534 // Map the whole region at once, assumed to be allocated contiguously. |
373 ReservedSpace FileMapInfo::reserve_shared_memory() { | 535 ReservedSpace FileMapInfo::reserve_shared_memory() { |
374 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0]; | 536 struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[0]; |
375 char* requested_addr = si->_base; | 537 char* requested_addr = si->_base; |
376 | 538 |
377 size_t size = FileMapInfo::shared_spaces_size(); | 539 size_t size = FileMapInfo::shared_spaces_size(); |
378 | 540 |
379 // Reserve the space first, then map otherwise map will go right over some | 541 // Reserve the space first, then map otherwise map will go right over some |
391 | 553 |
392 // Memory map a region in the address space. | 554 // Memory map a region in the address space. |
393 static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode"}; | 555 static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode"}; |
394 | 556 |
395 char* FileMapInfo::map_region(int i) { | 557 char* FileMapInfo::map_region(int i) { |
396 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; | 558 struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i]; |
397 size_t used = si->_used; | 559 size_t used = si->_used; |
398 size_t alignment = os::vm_allocation_granularity(); | 560 size_t alignment = os::vm_allocation_granularity(); |
399 size_t size = align_size_up(used, alignment); | 561 size_t size = align_size_up(used, alignment); |
400 char *requested_addr = si->_base; | 562 char *requested_addr = si->_base; |
401 | 563 |
417 | 579 |
418 bool FileMapInfo::verify_region_checksum(int i) { | 580 bool FileMapInfo::verify_region_checksum(int i) { |
419 if (!VerifySharedSpaces) { | 581 if (!VerifySharedSpaces) { |
420 return true; | 582 return true; |
421 } | 583 } |
422 const char* buf = _header._space[i]._base; | 584 const char* buf = _header->_space[i]._base; |
423 size_t sz = _header._space[i]._used; | 585 size_t sz = _header->_space[i]._used; |
424 int crc = ClassLoader::crc32(0, buf, (jint)sz); | 586 int crc = ClassLoader::crc32(0, buf, (jint)sz); |
425 if (crc != _header._space[i]._crc) { | 587 if (crc != _header->_space[i]._crc) { |
426 fail_continue("Checksum verification failed."); | 588 fail_continue("Checksum verification failed."); |
427 return false; | 589 return false; |
428 } | 590 } |
429 return true; | 591 return true; |
430 } | 592 } |
431 | 593 |
432 // Unmap a memory region in the address space. | 594 // Unmap a memory region in the address space. |
433 | 595 |
434 void FileMapInfo::unmap_region(int i) { | 596 void FileMapInfo::unmap_region(int i) { |
435 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; | 597 struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i]; |
436 size_t used = si->_used; | 598 size_t used = si->_used; |
437 size_t size = align_size_up(used, os::vm_allocation_granularity()); | 599 size_t size = align_size_up(used, os::vm_allocation_granularity()); |
438 if (!os::unmap_memory(si->_base, size)) { | 600 if (!os::unmap_memory(si->_base, size)) { |
439 fail_stop("Unable to unmap shared space."); | 601 fail_stop("Unable to unmap shared space."); |
440 } | 602 } |
447 } | 609 } |
448 } | 610 } |
449 | 611 |
450 | 612 |
451 FileMapInfo* FileMapInfo::_current_info = NULL; | 613 FileMapInfo* FileMapInfo::_current_info = NULL; |
452 | 614 SharedClassPathEntry* FileMapInfo::_classpath_entry_table = NULL; |
615 int FileMapInfo::_classpath_entry_table_size = 0; | |
616 size_t FileMapInfo::_classpath_entry_size = 0x1234baad; | |
617 bool FileMapInfo::_validating_classpath_entry_table = false; | |
453 | 618 |
454 // Open the shared archive file, read and validate the header | 619 // Open the shared archive file, read and validate the header |
455 // information (version, boot classpath, etc.). If initialization | 620 // information (version, boot classpath, etc.). If initialization |
456 // fails, shared spaces are disabled and the file is closed. [See | 621 // fails, shared spaces are disabled and the file is closed. [See |
457 // fail_continue.] | 622 // fail_continue.] |
623 // | |
624 // Validation of the archive is done in two steps: | |
625 // | |
626 // [1] validate_header() - done here. This checks the header, including _paths_misc_info. | |
627 // [2] validate_classpath_entry_table - this is done later, because the table is in the RW | |
628 // region of the archive, which is not mapped yet. | |
458 bool FileMapInfo::initialize() { | 629 bool FileMapInfo::initialize() { |
459 assert(UseSharedSpaces, "UseSharedSpaces expected."); | 630 assert(UseSharedSpaces, "UseSharedSpaces expected."); |
460 | 631 |
461 if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space()) { | 632 if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space()) { |
462 fail_continue("Tool agent requires sharing to be disabled."); | 633 fail_continue("Tool agent requires sharing to be disabled."); |
466 if (!open_for_read()) { | 637 if (!open_for_read()) { |
467 return false; | 638 return false; |
468 } | 639 } |
469 | 640 |
470 init_from_file(_fd); | 641 init_from_file(_fd); |
471 if (!validate()) { | 642 if (!validate_header()) { |
472 return false; | 643 return false; |
473 } | 644 } |
474 | 645 |
475 SharedReadOnlySize = _header._space[0]._capacity; | 646 SharedReadOnlySize = _header->_space[0]._capacity; |
476 SharedReadWriteSize = _header._space[1]._capacity; | 647 SharedReadWriteSize = _header->_space[1]._capacity; |
477 SharedMiscDataSize = _header._space[2]._capacity; | 648 SharedMiscDataSize = _header->_space[2]._capacity; |
478 SharedMiscCodeSize = _header._space[3]._capacity; | 649 SharedMiscCodeSize = _header->_space[3]._capacity; |
479 return true; | 650 return true; |
480 } | 651 } |
481 | 652 |
482 int FileMapInfo::compute_header_crc() { | 653 int FileMapInfo::FileMapHeader::compute_crc() { |
483 char* header = (char*)&_header; | 654 char* header = data(); |
484 // start computing from the field after _crc | 655 // start computing from the field after _crc |
485 char* buf = (char*)&_header._crc + sizeof(int); | 656 char* buf = (char*)&_crc + sizeof(int); |
486 size_t sz = sizeof(FileMapInfo::FileMapHeader) - (buf - header); | 657 size_t sz = data_size() - (buf - header); |
487 int crc = ClassLoader::crc32(0, buf, (jint)sz); | 658 int crc = ClassLoader::crc32(0, buf, (jint)sz); |
488 return crc; | 659 return crc; |
489 } | 660 } |
490 | 661 |
491 bool FileMapInfo::validate() { | 662 int FileMapInfo::compute_header_crc() { |
492 if (VerifySharedSpaces && compute_header_crc() != _header._crc) { | 663 return _header->compute_crc(); |
664 } | |
665 | |
666 bool FileMapInfo::FileMapHeader::validate() { | |
667 if (_magic != (int)0xf00baba2) { | |
668 FileMapInfo::fail_continue("The shared archive file has a bad magic number."); | |
669 return false; | |
670 } | |
671 if (VerifySharedSpaces && compute_crc() != _crc) { | |
493 fail_continue("Header checksum verification failed."); | 672 fail_continue("Header checksum verification failed."); |
494 return false; | 673 return false; |
495 } | 674 } |
496 if (_header._version != current_version()) { | 675 if (_version != current_version()) { |
497 fail_continue("The shared archive file is the wrong version."); | 676 FileMapInfo::fail_continue("The shared archive file is the wrong version."); |
498 return false; | 677 |
499 } | |
500 if (_header._magic != (int)0xf00baba2) { | |
501 fail_continue("The shared archive file has a bad magic number."); | |
502 return false; | 678 return false; |
503 } | 679 } |
504 char header_version[JVM_IDENT_MAX]; | 680 char header_version[JVM_IDENT_MAX]; |
505 get_header_version(header_version); | 681 get_header_version(header_version); |
506 if (strncmp(_header._jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) { | 682 if (strncmp(_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) { |
507 fail_continue("The shared archive file was created by a different" | 683 if (TraceClassPaths) { |
508 " version or build of HotSpot."); | 684 tty->print_cr("Expected: %s", header_version); |
509 return false; | 685 tty->print_cr("Actual: %s", _jvm_ident); |
510 } | 686 } |
511 if (_header._obj_alignment != ObjectAlignmentInBytes) { | 687 FileMapInfo::fail_continue("The shared archive file was created by a different" |
512 fail_continue("The shared archive file's ObjectAlignmentInBytes of %d" | 688 " version or build of HotSpot"); |
689 return false; | |
690 } | |
691 if (_obj_alignment != ObjectAlignmentInBytes) { | |
692 FileMapInfo::fail_continue("The shared archive file's ObjectAlignmentInBytes of %d" | |
513 " does not equal the current ObjectAlignmentInBytes of %d.", | 693 " does not equal the current ObjectAlignmentInBytes of %d.", |
514 _header._obj_alignment, ObjectAlignmentInBytes); | 694 _obj_alignment, ObjectAlignmentInBytes); |
515 return false; | 695 return false; |
516 } | 696 } |
517 | 697 |
518 // Cannot verify interpreter yet, as it can only be created after the GC | 698 return true; |
519 // heap has been initialized. | 699 } |
520 | 700 |
521 if (_header._num_jars >= JVM_SHARED_JARS_MAX) { | 701 bool FileMapInfo::validate_header() { |
522 fail_continue("Too many jar files to share."); | 702 bool status = _header->validate(); |
523 return false; | 703 |
524 } | 704 if (status) { |
525 | 705 if (!ClassLoader::check_shared_paths_misc_info(_paths_misc_info, _header->_paths_misc_info_size)) { |
526 // Build checks on classpath and jar files | 706 if (!PrintSharedArchiveAndExit) { |
527 int num_jars_now = 0; | 707 fail_continue("shared class paths mismatch (hint: enable -XX:+TraceClassPaths to diagnose the failure)"); |
528 ClassPathEntry *cpe = ClassLoader::classpath_entry(0); | 708 status = false; |
529 for ( ; cpe != NULL; cpe = cpe->next()) { | |
530 | |
531 if (cpe->is_jar_file()) { | |
532 if (num_jars_now < _header._num_jars) { | |
533 | |
534 // Jar file - verify timestamp and file size. | |
535 struct stat st; | |
536 const char *path = cpe->name(); | |
537 if (os::stat(path, &st) != 0) { | |
538 fail_continue("Unable to open jar file %s.", path); | |
539 return false; | |
540 } | |
541 if (_header._jar[num_jars_now]._timestamp != st.st_mtime || | |
542 _header._jar[num_jars_now]._filesize != st.st_size) { | |
543 fail_continue("A jar file is not the one used while building" | |
544 " the shared archive file."); | |
545 return false; | |
546 } | |
547 } | 709 } |
548 ++num_jars_now; | 710 } |
549 } else { | 711 } |
550 | 712 |
551 // If directories appear in boot classpath, they must be empty to | 713 if (_paths_misc_info != NULL) { |
552 // avoid having to verify each individual class file. | 714 FREE_C_HEAP_ARRAY(char, _paths_misc_info, mtClass); |
553 const char* name = ((ClassPathDirEntry*)cpe)->name(); | 715 _paths_misc_info = NULL; |
554 if (!os::dir_is_empty(name)) { | 716 } |
555 fail_continue("Boot classpath directory %s is not empty.", name); | 717 return status; |
556 return false; | |
557 } | |
558 } | |
559 } | |
560 if (num_jars_now < _header._num_jars) { | |
561 fail_continue("The number of jar files in the boot classpath is" | |
562 " less than the number the shared archive was created with."); | |
563 return false; | |
564 } | |
565 | |
566 return true; | |
567 } | 718 } |
568 | 719 |
569 // The following method is provided to see whether a given pointer | 720 // The following method is provided to see whether a given pointer |
570 // falls in the mapped shared space. | 721 // falls in the mapped shared space. |
571 // Param: | 722 // Param: |
572 // p, The given pointer | 723 // p, The given pointer |
573 // Return: | 724 // Return: |
574 // True if the p is within the mapped shared space, otherwise, false. | 725 // True if the p is within the mapped shared space, otherwise, false. |
575 bool FileMapInfo::is_in_shared_space(const void* p) { | 726 bool FileMapInfo::is_in_shared_space(const void* p) { |
576 for (int i = 0; i < MetaspaceShared::n_regions; i++) { | 727 for (int i = 0; i < MetaspaceShared::n_regions; i++) { |
577 if (p >= _header._space[i]._base && | 728 if (p >= _header->_space[i]._base && |
578 p < _header._space[i]._base + _header._space[i]._used) { | 729 p < _header->_space[i]._base + _header->_space[i]._used) { |
579 return true; | 730 return true; |
580 } | 731 } |
581 } | 732 } |
582 | 733 |
583 return false; | 734 return false; |
584 } | 735 } |
585 | 736 |
586 void FileMapInfo::print_shared_spaces() { | 737 void FileMapInfo::print_shared_spaces() { |
587 gclog_or_tty->print_cr("Shared Spaces:"); | 738 gclog_or_tty->print_cr("Shared Spaces:"); |
588 for (int i = 0; i < MetaspaceShared::n_regions; i++) { | 739 for (int i = 0; i < MetaspaceShared::n_regions; i++) { |
589 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; | 740 struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i]; |
590 gclog_or_tty->print(" %s " INTPTR_FORMAT "-" INTPTR_FORMAT, | 741 gclog_or_tty->print(" %s " INTPTR_FORMAT "-" INTPTR_FORMAT, |
591 shared_region_name[i], | 742 shared_region_name[i], |
592 si->_base, si->_base + si->_used); | 743 si->_base, si->_base + si->_used); |
593 } | 744 } |
594 } | 745 } |
597 void FileMapInfo::stop_sharing_and_unmap(const char* msg) { | 748 void FileMapInfo::stop_sharing_and_unmap(const char* msg) { |
598 FileMapInfo *map_info = FileMapInfo::current_info(); | 749 FileMapInfo *map_info = FileMapInfo::current_info(); |
599 if (map_info) { | 750 if (map_info) { |
600 map_info->fail_continue(msg); | 751 map_info->fail_continue(msg); |
601 for (int i = 0; i < MetaspaceShared::n_regions; i++) { | 752 for (int i = 0; i < MetaspaceShared::n_regions; i++) { |
602 if (map_info->_header._space[i]._base != NULL) { | 753 if (map_info->_header->_space[i]._base != NULL) { |
603 map_info->unmap_region(i); | 754 map_info->unmap_region(i); |
604 map_info->_header._space[i]._base = NULL; | 755 map_info->_header->_space[i]._base = NULL; |
605 } | 756 } |
606 } | 757 } |
607 } else if (DumpSharedSpaces) { | 758 } else if (DumpSharedSpaces) { |
608 fail_stop(msg, NULL); | 759 fail_stop(msg, NULL); |
609 } | 760 } |