Mercurial > hg > graal-jvmci-8
annotate src/share/vm/memory/filemap.cpp @ 2368:dde920245681
6896099: Integrate CMS heap ergo with default heap sizing ergo
6627787: CMS: JVM refuses to start up with -Xms16m -Xmx16m
7000125: CMS: Anti-monotone young gen sizing with respect to maximum whole heap size specification
7027529: CMS: retire CMSUseOldDefaults flag
Summary: Simplify CMS heap sizing code, relying on ergonomic initial sizing consistent with other collectors for the most part, controlling only young gen sizing to rein in pause times. Make CMS young gen sizing default statically cpu-dependant. Remove inconsistencies wrt generation sizing and policy code, allowing for the fixing for 6627787 and 7000125. For 7027529, retire the flag CMSUseOldDefaults which had been introduced as a bridge from JDK 5 to JDK 6 a number of years ago.
Reviewed-by: brutisso, poonam
author | ysr |
---|---|
date | Wed, 16 Mar 2011 10:37:08 -0700 |
parents | 828eafbd85cc |
children | da91efe96a93 |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
605
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
605
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
605
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/classLoader.hpp" | |
27 #include "classfile/symbolTable.hpp" | |
28 #include "memory/filemap.hpp" | |
29 #include "runtime/arguments.hpp" | |
30 #include "runtime/java.hpp" | |
31 #include "runtime/os.hpp" | |
32 #include "utilities/defaultStream.hpp" | |
33 | |
0 | 34 # include <sys/stat.h> |
35 # include <errno.h> | |
36 | |
37 #ifndef O_BINARY // if defined (Win32) use binary files. | |
38 #define O_BINARY 0 // otherwise do nothing. | |
39 #endif | |
40 | |
41 | |
42 extern address JVM_FunctionAtStart(); | |
43 extern address JVM_FunctionAtEnd(); | |
44 | |
605 | 45 // Complain and stop. All error conditions occurring during the writing of |
0 | 46 // an archive file should stop the process. Unrecoverable errors during |
47 // the reading of the archive file should stop the process. | |
48 | |
49 static void fail(const char *msg, va_list ap) { | |
50 // This occurs very early during initialization: tty is not initialized. | |
51 jio_fprintf(defaultStream::error_stream(), | |
605 | 52 "An error has occurred while processing the" |
0 | 53 " shared archive file.\n"); |
54 jio_vfprintf(defaultStream::error_stream(), msg, ap); | |
55 jio_fprintf(defaultStream::error_stream(), "\n"); | |
56 vm_exit_during_initialization("Unable to use shared archive.", NULL); | |
57 } | |
58 | |
59 | |
60 void FileMapInfo::fail_stop(const char *msg, ...) { | |
61 va_list ap; | |
62 va_start(ap, msg); | |
63 fail(msg, ap); // Never returns. | |
64 va_end(ap); // for completeness. | |
65 } | |
66 | |
67 | |
68 // Complain and continue. Recoverable errors during the reading of the | |
69 // archive file may continue (with sharing disabled). | |
70 // | |
71 // If we continue, then disable shared spaces and close the file. | |
72 | |
73 void FileMapInfo::fail_continue(const char *msg, ...) { | |
74 va_list ap; | |
75 va_start(ap, msg); | |
76 if (RequireSharedSpaces) { | |
77 fail(msg, ap); | |
78 } | |
79 va_end(ap); | |
80 UseSharedSpaces = false; | |
81 close(); | |
82 } | |
83 | |
84 | |
85 // Fill in the fileMapInfo structure with data about this VM instance. | |
86 | |
87 void FileMapInfo::populate_header(size_t alignment) { | |
88 _header._magic = 0xf00baba2; | |
89 _header._version = _current_version; | |
90 _header._alignment = alignment; | |
91 | |
92 // The following fields are for sanity checks for whether this archive | |
93 // will function correctly with this JVM and the bootclasspath it's | |
94 // invoked with. | |
95 | |
96 // JVM version string ... changes on each build. | |
97 const char *vm_version = VM_Version::internal_vm_info_string(); | |
98 if (strlen(vm_version) < (JVM_IDENT_MAX-1)) { | |
99 strcpy(_header._jvm_ident, vm_version); | |
100 } else { | |
101 fail_stop("JVM Ident field for shared archive is too long" | |
102 " - truncated to <%s>", _header._jvm_ident); | |
103 } | |
104 | |
105 // Build checks on classpath and jar files | |
106 _header._num_jars = 0; | |
107 ClassPathEntry *cpe = ClassLoader::classpath_entry(0); | |
108 for ( ; cpe != NULL; cpe = cpe->next()) { | |
109 | |
110 if (cpe->is_jar_file()) { | |
111 if (_header._num_jars >= JVM_SHARED_JARS_MAX) { | |
112 fail_stop("Too many jar files to share.", NULL); | |
113 } | |
114 | |
115 // Jar file - record timestamp and file size. | |
116 struct stat st; | |
117 const char *path = cpe->name(); | |
118 if (os::stat(path, &st) != 0) { | |
119 // If we can't access a jar file in the boot path, then we can't | |
120 // make assumptions about where classes get loaded from. | |
121 fail_stop("Unable to open jar file %s.", path); | |
122 } | |
123 _header._jar[_header._num_jars]._timestamp = st.st_mtime; | |
124 _header._jar[_header._num_jars]._filesize = st.st_size; | |
125 _header._num_jars++; | |
126 } else { | |
127 | |
128 // If directories appear in boot classpath, they must be empty to | |
129 // avoid having to verify each individual class file. | |
130 const char* name = ((ClassPathDirEntry*)cpe)->name(); | |
131 if (!os::dir_is_empty(name)) { | |
132 fail_stop("Boot classpath directory %s is not empty.", name); | |
133 } | |
134 } | |
135 } | |
136 } | |
137 | |
138 | |
139 // Read the FileMapInfo information from the file. | |
140 | |
141 bool FileMapInfo::init_from_file(int fd) { | |
142 | |
143 size_t n = read(fd, &_header, sizeof(struct FileMapHeader)); | |
144 if (n != sizeof(struct FileMapHeader)) { | |
145 fail_continue("Unable to read the file header."); | |
146 return false; | |
147 } | |
148 if (_header._version != current_version()) { | |
149 fail_continue("The shared archive file has the wrong version."); | |
150 return false; | |
151 } | |
152 _file_offset = (long)n; | |
153 return true; | |
154 } | |
155 | |
156 | |
157 // Read the FileMapInfo information from the file. | |
158 bool FileMapInfo::open_for_read() { | |
159 _full_path = Arguments::GetSharedArchivePath(); | |
160 int fd = open(_full_path, O_RDONLY | O_BINARY, 0); | |
161 if (fd < 0) { | |
162 if (errno == ENOENT) { | |
163 // Not locating the shared archive is ok. | |
164 fail_continue("Specified shared archive not found."); | |
165 } else { | |
166 fail_continue("Failed to open shared archive file (%s).", | |
167 strerror(errno)); | |
168 } | |
169 return false; | |
170 } | |
171 | |
172 _fd = fd; | |
173 _file_open = true; | |
174 return true; | |
175 } | |
176 | |
177 | |
178 // Write the FileMapInfo information to the file. | |
179 | |
180 void FileMapInfo::open_for_write() { | |
181 _full_path = Arguments::GetSharedArchivePath(); | |
182 if (PrintSharedSpaces) { | |
183 tty->print_cr("Dumping shared data to file: "); | |
184 tty->print_cr(" %s", _full_path); | |
185 } | |
186 | |
187 // Remove the existing file in case another process has it open. | |
188 remove(_full_path); | |
189 int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444); | |
190 if (fd < 0) { | |
191 fail_stop("Unable to create shared archive file %s.", _full_path); | |
192 } | |
193 _fd = fd; | |
194 _file_offset = 0; | |
195 _file_open = true; | |
196 } | |
197 | |
198 | |
199 // Write the header to the file, seek to the next allocation boundary. | |
200 | |
201 void FileMapInfo::write_header() { | |
202 write_bytes_aligned(&_header, sizeof(FileMapHeader)); | |
203 } | |
204 | |
205 | |
206 // Dump shared spaces to file. | |
207 | |
208 void FileMapInfo::write_space(int i, CompactibleSpace* space, bool read_only) { | |
209 align_file_position(); | |
210 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; | |
211 write_region(i, (char*)space->bottom(), space->used(), | |
212 space->capacity(), read_only, false); | |
213 } | |
214 | |
215 | |
216 // Dump region to file. | |
217 | |
218 void FileMapInfo::write_region(int region, char* base, size_t size, | |
219 size_t capacity, bool read_only, | |
220 bool allow_exec) { | |
221 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[region]; | |
222 | |
223 if (_file_open) { | |
224 guarantee(si->_file_offset == _file_offset, "file offset mismatch."); | |
225 if (PrintSharedSpaces) { | |
226 tty->print_cr("Shared file region %d: 0x%x bytes, addr 0x%x," | |
227 " file offset 0x%x", region, size, base, _file_offset); | |
228 } | |
229 } else { | |
230 si->_file_offset = _file_offset; | |
231 } | |
232 si->_base = base; | |
233 si->_used = size; | |
234 si->_capacity = capacity; | |
235 si->_read_only = read_only; | |
236 si->_allow_exec = allow_exec; | |
237 write_bytes_aligned(base, (int)size); | |
238 } | |
239 | |
240 | |
241 // Dump bytes to file -- at the current file position. | |
242 | |
243 void FileMapInfo::write_bytes(const void* buffer, int nbytes) { | |
244 if (_file_open) { | |
245 int n = ::write(_fd, buffer, nbytes); | |
246 if (n != nbytes) { | |
247 // It is dangerous to leave the corrupted shared archive file around, | |
248 // close and remove the file. See bug 6372906. | |
249 close(); | |
250 remove(_full_path); | |
251 fail_stop("Unable to write to shared archive file.", NULL); | |
252 } | |
253 } | |
254 _file_offset += nbytes; | |
255 } | |
256 | |
257 | |
258 // Align file position to an allocation unit boundary. | |
259 | |
260 void FileMapInfo::align_file_position() { | |
261 long new_file_offset = align_size_up(_file_offset, os::vm_allocation_granularity()); | |
262 if (new_file_offset != _file_offset) { | |
263 _file_offset = new_file_offset; | |
264 if (_file_open) { | |
265 // Seek one byte back from the target and write a byte to insure | |
266 // that the written file is the correct length. | |
267 _file_offset -= 1; | |
268 if (lseek(_fd, _file_offset, SEEK_SET) < 0) { | |
269 fail_stop("Unable to seek.", NULL); | |
270 } | |
271 char zero = 0; | |
272 write_bytes(&zero, 1); | |
273 } | |
274 } | |
275 } | |
276 | |
277 | |
278 // Dump bytes to file -- at the current file position. | |
279 | |
280 void FileMapInfo::write_bytes_aligned(const void* buffer, int nbytes) { | |
281 align_file_position(); | |
282 write_bytes(buffer, nbytes); | |
283 align_file_position(); | |
284 } | |
285 | |
286 | |
287 // Close the shared archive file. This does NOT unmap mapped regions. | |
288 | |
289 void FileMapInfo::close() { | |
290 if (_file_open) { | |
291 if (::close(_fd) < 0) { | |
292 fail_stop("Unable to close the shared archive file."); | |
293 } | |
294 _file_open = false; | |
295 _fd = -1; | |
296 } | |
297 } | |
298 | |
299 | |
300 // Memory map a shared space from the archive file. | |
301 | |
302 bool FileMapInfo::map_space(int i, ReservedSpace rs, ContiguousSpace* space) { | |
303 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; | |
304 if (space != NULL) { | |
305 if (si->_base != (char*)space->bottom() || | |
306 si->_capacity != space->capacity()) { | |
307 fail_continue("Shared space base address does not match."); | |
308 return false; | |
309 } | |
310 } | |
311 bool result = (map_region(i, rs) != NULL); | |
312 if (space != NULL && result) { | |
313 space->set_top((HeapWord*)(si->_base + si->_used)); | |
314 space->set_saved_mark(); | |
315 } | |
316 return result; | |
317 } | |
318 | |
319 | |
320 // JVM/TI RedefineClasses() support: | |
321 // Remap the shared readonly space to shared readwrite, private. | |
322 bool FileMapInfo::remap_shared_readonly_as_readwrite() { | |
323 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0]; | |
324 if (!si->_read_only) { | |
325 // the space is already readwrite so we are done | |
326 return true; | |
327 } | |
328 size_t used = si->_used; | |
329 size_t size = align_size_up(used, os::vm_allocation_granularity()); | |
330 if (!open_for_read()) { | |
331 return false; | |
332 } | |
333 char *base = os::remap_memory(_fd, _full_path, si->_file_offset, | |
334 si->_base, size, false /* !read_only */, | |
335 si->_allow_exec); | |
336 close(); | |
337 if (base == NULL) { | |
338 fail_continue("Unable to remap shared readonly space (errno=%d).", errno); | |
339 return false; | |
340 } | |
341 if (base != si->_base) { | |
342 fail_continue("Unable to remap shared readonly space at required address."); | |
343 return false; | |
344 } | |
345 si->_read_only = false; | |
346 return true; | |
347 } | |
348 | |
349 | |
350 // Memory map a region in the address space. | |
351 | |
352 char* FileMapInfo::map_region(int i, ReservedSpace rs) { | |
353 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; | |
354 size_t used = si->_used; | |
355 size_t size = align_size_up(used, os::vm_allocation_granularity()); | |
356 | |
357 ReservedSpace mapped_rs = rs.first_part(size, true, true); | |
358 ReservedSpace unmapped_rs = rs.last_part(size); | |
359 mapped_rs.release(); | |
360 | |
361 return map_region(i, true); | |
362 } | |
363 | |
364 | |
365 // Memory map a region in the address space. | |
366 | |
367 char* FileMapInfo::map_region(int i, bool address_must_match) { | |
368 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; | |
369 size_t used = si->_used; | |
370 size_t size = align_size_up(used, os::vm_allocation_granularity()); | |
371 char *requested_addr = 0; | |
372 if (address_must_match) { | |
373 requested_addr = si->_base; | |
374 } | |
375 char *base = os::map_memory(_fd, _full_path, si->_file_offset, | |
376 requested_addr, size, si->_read_only, | |
377 si->_allow_exec); | |
378 if (base == NULL) { | |
379 fail_continue("Unable to map shared space."); | |
380 return NULL; | |
381 } | |
382 if (address_must_match) { | |
383 if (base != si->_base) { | |
384 fail_continue("Unable to map shared space at required address."); | |
385 return NULL; | |
386 } | |
387 } else { | |
388 si->_base = base; // save mapped address for unmapping. | |
389 } | |
390 return base; | |
391 } | |
392 | |
393 | |
394 // Unmap a memory region in the address space. | |
395 | |
396 void FileMapInfo::unmap_region(int i) { | |
397 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; | |
398 size_t used = si->_used; | |
399 size_t size = align_size_up(used, os::vm_allocation_granularity()); | |
400 if (!os::unmap_memory(si->_base, size)) { | |
401 fail_stop("Unable to unmap shared space."); | |
402 } | |
403 } | |
404 | |
405 | |
406 void FileMapInfo::assert_mark(bool check) { | |
407 if (!check) { | |
408 fail_stop("Mark mismatch while restoring from shared file.", NULL); | |
409 } | |
410 } | |
411 | |
412 | |
413 FileMapInfo* FileMapInfo::_current_info = NULL; | |
414 | |
415 | |
416 // Open the shared archive file, read and validate the header | |
417 // information (version, boot classpath, etc.). If initialization | |
418 // fails, shared spaces are disabled and the file is closed. [See | |
419 // fail_continue.] | |
420 | |
421 | |
422 bool FileMapInfo::initialize() { | |
423 assert(UseSharedSpaces, "UseSharedSpaces expected."); | |
424 | |
425 if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space()) { | |
426 fail_continue("Tool agent requires sharing to be disabled."); | |
427 return false; | |
428 } | |
429 | |
430 if (!open_for_read()) { | |
431 return false; | |
432 } | |
433 | |
434 init_from_file(_fd); | |
435 if (!validate()) { | |
436 return false; | |
437 } | |
438 | |
439 SharedReadOnlySize = _header._space[0]._capacity; | |
440 SharedReadWriteSize = _header._space[1]._capacity; | |
441 SharedMiscDataSize = _header._space[2]._capacity; | |
442 SharedMiscCodeSize = _header._space[3]._capacity; | |
443 return true; | |
444 } | |
445 | |
446 | |
447 bool FileMapInfo::validate() { | |
448 if (_header._version != current_version()) { | |
449 fail_continue("The shared archive file is the wrong version."); | |
450 return false; | |
451 } | |
452 if (_header._magic != (int)0xf00baba2) { | |
453 fail_continue("The shared archive file has a bad magic number."); | |
454 return false; | |
455 } | |
456 if (strncmp(_header._jvm_ident, VM_Version::internal_vm_info_string(), | |
457 JVM_IDENT_MAX-1) != 0) { | |
458 fail_continue("The shared archive file was created by a different" | |
459 " version or build of HotSpot."); | |
460 return false; | |
461 } | |
462 | |
463 // Cannot verify interpreter yet, as it can only be created after the GC | |
464 // heap has been initialized. | |
465 | |
466 if (_header._num_jars >= JVM_SHARED_JARS_MAX) { | |
467 fail_continue("Too many jar files to share."); | |
468 return false; | |
469 } | |
470 | |
471 // Build checks on classpath and jar files | |
472 int num_jars_now = 0; | |
473 ClassPathEntry *cpe = ClassLoader::classpath_entry(0); | |
474 for ( ; cpe != NULL; cpe = cpe->next()) { | |
475 | |
476 if (cpe->is_jar_file()) { | |
477 if (num_jars_now < _header._num_jars) { | |
478 | |
479 // Jar file - verify timestamp and file size. | |
480 struct stat st; | |
481 const char *path = cpe->name(); | |
482 if (os::stat(path, &st) != 0) { | |
483 fail_continue("Unable to open jar file %s.", path); | |
484 return false; | |
485 } | |
486 if (_header._jar[num_jars_now]._timestamp != st.st_mtime || | |
487 _header._jar[num_jars_now]._filesize != st.st_size) { | |
488 fail_continue("A jar file is not the one used while building" | |
489 " the shared archive file."); | |
490 return false; | |
491 } | |
492 } | |
493 ++num_jars_now; | |
494 } else { | |
495 | |
496 // If directories appear in boot classpath, they must be empty to | |
497 // avoid having to verify each individual class file. | |
498 const char* name = ((ClassPathDirEntry*)cpe)->name(); | |
499 if (!os::dir_is_empty(name)) { | |
500 fail_continue("Boot classpath directory %s is not empty.", name); | |
501 return false; | |
502 } | |
503 } | |
504 } | |
505 if (num_jars_now < _header._num_jars) { | |
506 fail_continue("The number of jar files in the boot classpath is" | |
507 " less than the number the shared archive was created with."); | |
508 return false; | |
509 } | |
510 | |
511 return true; | |
512 } | |
513 | |
514 // The following method is provided to see whether a given pointer | |
515 // falls in the mapped shared space. | |
516 // Param: | |
517 // p, The given pointer | |
518 // Return: | |
519 // True if the p is within the mapped shared space, otherwise, false. | |
520 bool FileMapInfo::is_in_shared_space(const void* p) { | |
521 for (int i = 0; i < CompactingPermGenGen::n_regions; i++) { | |
522 if (p >= _header._space[i]._base && | |
523 p < _header._space[i]._base + _header._space[i]._used) { | |
524 return true; | |
525 } | |
526 } | |
527 | |
528 return false; | |
529 } |