Mercurial > hg > graal-compiler
annotate src/share/vm/memory/filemap.cpp @ 8804:91bf0bdae37b
8008217: CDS: Class data sharing limits the malloc heap on Solaris
Summary: In 64bit VM move CDS archive address to 32G on all platforms using new flag SharedBaseAddress. In 32bit VM set CDS archive address to 3Gb on Linux and let other OSs pick the address.
Reviewed-by: kvn, dcubed, zgu, hseigel
author | coleenp |
---|---|
date | Wed, 20 Mar 2013 08:04:54 -0400 |
parents | c4ef3380a70b |
children | 868d87ed63c8 |
rev | line source |
---|---|
0 | 1 /* |
7980
c4ef3380a70b
7197672: There are issues with shared data on windows
hseigel
parents:
7461
diff
changeset
|
2 * Copyright (c) 2003, 2013, 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" | |
7174
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
28 #include "classfile/altHashing.hpp" |
1972 | 29 #include "memory/filemap.hpp" |
30 #include "runtime/arguments.hpp" | |
31 #include "runtime/java.hpp" | |
32 #include "runtime/os.hpp" | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6725
diff
changeset
|
33 #include "services/memTracker.hpp" |
1972 | 34 #include "utilities/defaultStream.hpp" |
35 | |
0 | 36 # include <sys/stat.h> |
37 # include <errno.h> | |
38 | |
39 #ifndef O_BINARY // if defined (Win32) use binary files. | |
40 #define O_BINARY 0 // otherwise do nothing. | |
41 #endif | |
42 | |
43 | |
44 extern address JVM_FunctionAtStart(); | |
45 extern address JVM_FunctionAtEnd(); | |
46 | |
605 | 47 // Complain and stop. All error conditions occurring during the writing of |
0 | 48 // an archive file should stop the process. Unrecoverable errors during |
49 // the reading of the archive file should stop the process. | |
50 | |
51 static void fail(const char *msg, va_list ap) { | |
52 // This occurs very early during initialization: tty is not initialized. | |
53 jio_fprintf(defaultStream::error_stream(), | |
605 | 54 "An error has occurred while processing the" |
0 | 55 " shared archive file.\n"); |
56 jio_vfprintf(defaultStream::error_stream(), msg, ap); | |
57 jio_fprintf(defaultStream::error_stream(), "\n"); | |
58 vm_exit_during_initialization("Unable to use shared archive.", NULL); | |
59 } | |
60 | |
61 | |
62 void FileMapInfo::fail_stop(const char *msg, ...) { | |
63 va_list ap; | |
64 va_start(ap, msg); | |
65 fail(msg, ap); // Never returns. | |
66 va_end(ap); // for completeness. | |
67 } | |
68 | |
69 | |
70 // Complain and continue. Recoverable errors during the reading of the | |
71 // archive file may continue (with sharing disabled). | |
72 // | |
73 // If we continue, then disable shared spaces and close the file. | |
74 | |
75 void FileMapInfo::fail_continue(const char *msg, ...) { | |
76 va_list ap; | |
77 va_start(ap, msg); | |
78 if (RequireSharedSpaces) { | |
79 fail(msg, ap); | |
80 } | |
81 va_end(ap); | |
82 UseSharedSpaces = false; | |
83 close(); | |
84 } | |
85 | |
7174
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
86 // Fill in the fileMapInfo structure with data about this VM instance. |
0 | 87 |
7174
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
88 // This method copies the vm version info into header_version. If the version is too |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
89 // long then a truncated version, which has a hash code appended to it, is copied. |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
90 // |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
91 // Using a template enables this method to verify that header_version is an array of |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
92 // length JVM_IDENT_MAX. This ensures that the code that writes to the CDS file and |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
93 // the code that reads the CDS file will both use the same size buffer. Hence, will |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
94 // use identical truncation. This is necessary for matching of truncated versions. |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
95 template <int N> static void get_header_version(char (&header_version) [N]) { |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
96 assert(N == JVM_IDENT_MAX, "Bad header_version size"); |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
97 |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
98 const char *vm_version = VM_Version::internal_vm_info_string(); |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
99 const int version_len = (int)strlen(vm_version); |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
100 |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
101 if (version_len < (JVM_IDENT_MAX-1)) { |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
102 strcpy(header_version, vm_version); |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
103 |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
104 } else { |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
105 // Get the hash value. Use a static seed because the hash needs to return the same |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
106 // value over multiple jvm invocations. |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
107 unsigned int hash = AltHashing::murmur3_32(8191, (const jbyte*)vm_version, version_len); |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
108 |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
109 // Truncate the ident, saving room for the 8 hex character hash value. |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
110 strncpy(header_version, vm_version, JVM_IDENT_MAX-9); |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
111 |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
112 // Append the hash code as eight hex digits. |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
113 sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash); |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
114 header_version[JVM_IDENT_MAX-1] = 0; // Null terminate. |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
115 } |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
116 } |
0 | 117 |
118 void FileMapInfo::populate_header(size_t alignment) { | |
119 _header._magic = 0xf00baba2; | |
120 _header._version = _current_version; | |
121 _header._alignment = alignment; | |
7461
561148896559
8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents:
7460
diff
changeset
|
122 _header._obj_alignment = ObjectAlignmentInBytes; |
0 | 123 |
124 // The following fields are for sanity checks for whether this archive | |
125 // will function correctly with this JVM and the bootclasspath it's | |
126 // invoked with. | |
127 | |
128 // JVM version string ... changes on each build. | |
7174
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
129 get_header_version(_header._jvm_ident); |
0 | 130 |
131 // Build checks on classpath and jar files | |
132 _header._num_jars = 0; | |
133 ClassPathEntry *cpe = ClassLoader::classpath_entry(0); | |
134 for ( ; cpe != NULL; cpe = cpe->next()) { | |
135 | |
136 if (cpe->is_jar_file()) { | |
137 if (_header._num_jars >= JVM_SHARED_JARS_MAX) { | |
138 fail_stop("Too many jar files to share.", NULL); | |
139 } | |
140 | |
141 // Jar file - record timestamp and file size. | |
142 struct stat st; | |
143 const char *path = cpe->name(); | |
144 if (os::stat(path, &st) != 0) { | |
145 // If we can't access a jar file in the boot path, then we can't | |
146 // make assumptions about where classes get loaded from. | |
147 fail_stop("Unable to open jar file %s.", path); | |
148 } | |
149 _header._jar[_header._num_jars]._timestamp = st.st_mtime; | |
150 _header._jar[_header._num_jars]._filesize = st.st_size; | |
151 _header._num_jars++; | |
152 } else { | |
153 | |
154 // If directories appear in boot classpath, they must be empty to | |
155 // avoid having to verify each individual class file. | |
156 const char* name = ((ClassPathDirEntry*)cpe)->name(); | |
157 if (!os::dir_is_empty(name)) { | |
158 fail_stop("Boot classpath directory %s is not empty.", name); | |
159 } | |
160 } | |
161 } | |
162 } | |
163 | |
164 | |
165 // Read the FileMapInfo information from the file. | |
166 | |
167 bool FileMapInfo::init_from_file(int fd) { | |
168 | |
169 size_t n = read(fd, &_header, sizeof(struct FileMapHeader)); | |
170 if (n != sizeof(struct FileMapHeader)) { | |
171 fail_continue("Unable to read the file header."); | |
172 return false; | |
173 } | |
174 if (_header._version != current_version()) { | |
175 fail_continue("The shared archive file has the wrong version."); | |
176 return false; | |
177 } | |
178 _file_offset = (long)n; | |
179 return true; | |
180 } | |
181 | |
182 | |
183 // Read the FileMapInfo information from the file. | |
184 bool FileMapInfo::open_for_read() { | |
185 _full_path = Arguments::GetSharedArchivePath(); | |
186 int fd = open(_full_path, O_RDONLY | O_BINARY, 0); | |
187 if (fd < 0) { | |
188 if (errno == ENOENT) { | |
189 // Not locating the shared archive is ok. | |
190 fail_continue("Specified shared archive not found."); | |
191 } else { | |
192 fail_continue("Failed to open shared archive file (%s).", | |
193 strerror(errno)); | |
194 } | |
195 return false; | |
196 } | |
197 | |
198 _fd = fd; | |
199 _file_open = true; | |
200 return true; | |
201 } | |
202 | |
203 | |
204 // Write the FileMapInfo information to the file. | |
205 | |
206 void FileMapInfo::open_for_write() { | |
207 _full_path = Arguments::GetSharedArchivePath(); | |
208 if (PrintSharedSpaces) { | |
209 tty->print_cr("Dumping shared data to file: "); | |
210 tty->print_cr(" %s", _full_path); | |
211 } | |
212 | |
7980
c4ef3380a70b
7197672: There are issues with shared data on windows
hseigel
parents:
7461
diff
changeset
|
213 #ifdef _WINDOWS // On Windows, need WRITE permission to remove the file. |
c4ef3380a70b
7197672: There are issues with shared data on windows
hseigel
parents:
7461
diff
changeset
|
214 chmod(_full_path, _S_IREAD | _S_IWRITE); |
c4ef3380a70b
7197672: There are issues with shared data on windows
hseigel
parents:
7461
diff
changeset
|
215 #endif |
c4ef3380a70b
7197672: There are issues with shared data on windows
hseigel
parents:
7461
diff
changeset
|
216 |
c4ef3380a70b
7197672: There are issues with shared data on windows
hseigel
parents:
7461
diff
changeset
|
217 // Use remove() to delete the existing file because, on Unix, this will |
c4ef3380a70b
7197672: There are issues with shared data on windows
hseigel
parents:
7461
diff
changeset
|
218 // allow processes that have it open continued access to the file. |
0 | 219 remove(_full_path); |
220 int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444); | |
221 if (fd < 0) { | |
222 fail_stop("Unable to create shared archive file %s.", _full_path); | |
223 } | |
224 _fd = fd; | |
225 _file_offset = 0; | |
226 _file_open = true; | |
227 } | |
228 | |
229 | |
230 // Write the header to the file, seek to the next allocation boundary. | |
231 | |
232 void FileMapInfo::write_header() { | |
233 write_bytes_aligned(&_header, sizeof(FileMapHeader)); | |
234 } | |
235 | |
236 | |
237 // Dump shared spaces to file. | |
238 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
239 void FileMapInfo::write_space(int i, Metaspace* space, bool read_only) { |
0 | 240 align_file_position(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
241 size_t used = space->used_words(Metaspace::NonClassType) * BytesPerWord; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
242 size_t capacity = space->capacity_words(Metaspace::NonClassType) * BytesPerWord; |
0 | 243 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
244 write_region(i, (char*)space->bottom(), used, capacity, read_only, false); |
0 | 245 } |
246 | |
247 | |
248 // Dump region to file. | |
249 | |
250 void FileMapInfo::write_region(int region, char* base, size_t size, | |
251 size_t capacity, bool read_only, | |
252 bool allow_exec) { | |
253 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[region]; | |
254 | |
255 if (_file_open) { | |
256 guarantee(si->_file_offset == _file_offset, "file offset mismatch."); | |
257 if (PrintSharedSpaces) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
258 tty->print_cr("Shared file region %d: 0x%6x bytes, addr " INTPTR_FORMAT |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
259 " file offset 0x%6x", region, size, base, _file_offset); |
0 | 260 } |
261 } else { | |
262 si->_file_offset = _file_offset; | |
263 } | |
264 si->_base = base; | |
265 si->_used = size; | |
266 si->_capacity = capacity; | |
267 si->_read_only = read_only; | |
268 si->_allow_exec = allow_exec; | |
269 write_bytes_aligned(base, (int)size); | |
270 } | |
271 | |
272 | |
273 // Dump bytes to file -- at the current file position. | |
274 | |
275 void FileMapInfo::write_bytes(const void* buffer, int nbytes) { | |
276 if (_file_open) { | |
277 int n = ::write(_fd, buffer, nbytes); | |
278 if (n != nbytes) { | |
279 // It is dangerous to leave the corrupted shared archive file around, | |
280 // close and remove the file. See bug 6372906. | |
281 close(); | |
282 remove(_full_path); | |
283 fail_stop("Unable to write to shared archive file.", NULL); | |
284 } | |
285 } | |
286 _file_offset += nbytes; | |
287 } | |
288 | |
289 | |
290 // Align file position to an allocation unit boundary. | |
291 | |
292 void FileMapInfo::align_file_position() { | |
293 long new_file_offset = align_size_up(_file_offset, os::vm_allocation_granularity()); | |
294 if (new_file_offset != _file_offset) { | |
295 _file_offset = new_file_offset; | |
296 if (_file_open) { | |
297 // Seek one byte back from the target and write a byte to insure | |
298 // that the written file is the correct length. | |
299 _file_offset -= 1; | |
300 if (lseek(_fd, _file_offset, SEEK_SET) < 0) { | |
301 fail_stop("Unable to seek.", NULL); | |
302 } | |
303 char zero = 0; | |
304 write_bytes(&zero, 1); | |
305 } | |
306 } | |
307 } | |
308 | |
309 | |
310 // Dump bytes to file -- at the current file position. | |
311 | |
312 void FileMapInfo::write_bytes_aligned(const void* buffer, int nbytes) { | |
313 align_file_position(); | |
314 write_bytes(buffer, nbytes); | |
315 align_file_position(); | |
316 } | |
317 | |
318 | |
319 // Close the shared archive file. This does NOT unmap mapped regions. | |
320 | |
321 void FileMapInfo::close() { | |
322 if (_file_open) { | |
323 if (::close(_fd) < 0) { | |
324 fail_stop("Unable to close the shared archive file."); | |
325 } | |
326 _file_open = false; | |
327 _fd = -1; | |
328 } | |
329 } | |
330 | |
331 | |
332 // JVM/TI RedefineClasses() support: | |
333 // Remap the shared readonly space to shared readwrite, private. | |
334 bool FileMapInfo::remap_shared_readonly_as_readwrite() { | |
335 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0]; | |
336 if (!si->_read_only) { | |
337 // the space is already readwrite so we are done | |
338 return true; | |
339 } | |
340 size_t used = si->_used; | |
341 size_t size = align_size_up(used, os::vm_allocation_granularity()); | |
342 if (!open_for_read()) { | |
343 return false; | |
344 } | |
345 char *base = os::remap_memory(_fd, _full_path, si->_file_offset, | |
346 si->_base, size, false /* !read_only */, | |
347 si->_allow_exec); | |
348 close(); | |
349 if (base == NULL) { | |
350 fail_continue("Unable to remap shared readonly space (errno=%d).", errno); | |
351 return false; | |
352 } | |
353 if (base != si->_base) { | |
354 fail_continue("Unable to remap shared readonly space at required address."); | |
355 return false; | |
356 } | |
357 si->_read_only = false; | |
358 return true; | |
359 } | |
360 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
361 // Map the whole region at once, assumed to be allocated contiguously. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
362 ReservedSpace FileMapInfo::reserve_shared_memory() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
363 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0]; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
364 char* requested_addr = si->_base; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
365 size_t alignment = os::vm_allocation_granularity(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
366 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
367 size_t size = align_size_up(SharedReadOnlySize + SharedReadWriteSize + |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
368 SharedMiscDataSize + SharedMiscCodeSize, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
369 alignment); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
370 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
371 // Reserve the space first, then map otherwise map will go right over some |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
372 // other reserved memory (like the code cache). |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
373 ReservedSpace rs(size, alignment, false, requested_addr); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
374 if (!rs.is_reserved()) { |
8804
91bf0bdae37b
8008217: CDS: Class data sharing limits the malloc heap on Solaris
coleenp
parents:
7980
diff
changeset
|
375 fail_continue(err_msg("Unable to reserve shared space at required address " INTPTR_FORMAT, requested_addr)); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
376 return rs; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
377 } |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6725
diff
changeset
|
378 // the reserved virtual memory is for mapping class data sharing archive |
7460
6c3f47d964f3
8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents:
7174
diff
changeset
|
379 MemTracker::record_virtual_memory_type((address)rs.base(), mtClassShared); |
6c3f47d964f3
8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents:
7174
diff
changeset
|
380 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
381 return rs; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
382 } |
0 | 383 |
384 // Memory map a region in the address space. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
385 static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode"}; |
0 | 386 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
387 char* FileMapInfo::map_region(int i) { |
0 | 388 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; |
389 size_t used = si->_used; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
390 size_t alignment = os::vm_allocation_granularity(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
391 size_t size = align_size_up(used, alignment); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
392 char *requested_addr = si->_base; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
393 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
394 // map the contents of the CDS archive in this memory |
0 | 395 char *base = os::map_memory(_fd, _full_path, si->_file_offset, |
396 requested_addr, size, si->_read_only, | |
397 si->_allow_exec); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
398 if (base == NULL || base != si->_base) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
399 fail_continue(err_msg("Unable to map %s shared space at required address.", shared_region_name[i])); |
0 | 400 return NULL; |
401 } | |
7460
6c3f47d964f3
8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents:
7174
diff
changeset
|
402 #ifdef _WINDOWS |
6c3f47d964f3
8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents:
7174
diff
changeset
|
403 // This call is Windows-only because the memory_type gets recorded for the other platforms |
6c3f47d964f3
8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents:
7174
diff
changeset
|
404 // in method FileMapInfo::reserve_shared_memory(), which is not called on Windows. |
6c3f47d964f3
8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents:
7174
diff
changeset
|
405 MemTracker::record_virtual_memory_type((address)base, mtClassShared); |
6c3f47d964f3
8003705: CDS failed on Windows: can not map in the CDS.
hseigel
parents:
7174
diff
changeset
|
406 #endif |
0 | 407 return base; |
408 } | |
409 | |
410 | |
411 // Unmap a memory region in the address space. | |
412 | |
413 void FileMapInfo::unmap_region(int i) { | |
414 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; | |
415 size_t used = si->_used; | |
416 size_t size = align_size_up(used, os::vm_allocation_granularity()); | |
417 if (!os::unmap_memory(si->_base, size)) { | |
418 fail_stop("Unable to unmap shared space."); | |
419 } | |
420 } | |
421 | |
422 | |
423 void FileMapInfo::assert_mark(bool check) { | |
424 if (!check) { | |
425 fail_stop("Mark mismatch while restoring from shared file.", NULL); | |
426 } | |
427 } | |
428 | |
429 | |
430 FileMapInfo* FileMapInfo::_current_info = NULL; | |
431 | |
432 | |
433 // Open the shared archive file, read and validate the header | |
434 // information (version, boot classpath, etc.). If initialization | |
435 // fails, shared spaces are disabled and the file is closed. [See | |
436 // fail_continue.] | |
437 bool FileMapInfo::initialize() { | |
438 assert(UseSharedSpaces, "UseSharedSpaces expected."); | |
439 | |
440 if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space()) { | |
441 fail_continue("Tool agent requires sharing to be disabled."); | |
442 return false; | |
443 } | |
444 | |
445 if (!open_for_read()) { | |
446 return false; | |
447 } | |
448 | |
449 init_from_file(_fd); | |
450 if (!validate()) { | |
451 return false; | |
452 } | |
453 | |
454 SharedReadOnlySize = _header._space[0]._capacity; | |
455 SharedReadWriteSize = _header._space[1]._capacity; | |
456 SharedMiscDataSize = _header._space[2]._capacity; | |
457 SharedMiscCodeSize = _header._space[3]._capacity; | |
458 return true; | |
459 } | |
460 | |
461 | |
462 bool FileMapInfo::validate() { | |
463 if (_header._version != current_version()) { | |
464 fail_continue("The shared archive file is the wrong version."); | |
465 return false; | |
466 } | |
467 if (_header._magic != (int)0xf00baba2) { | |
468 fail_continue("The shared archive file has a bad magic number."); | |
469 return false; | |
470 } | |
7174
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
471 char header_version[JVM_IDENT_MAX]; |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
472 get_header_version(header_version); |
fe81517cfb77
6924920: Class Data Sharing limit on the java version string can create failures
hseigel
parents:
6882
diff
changeset
|
473 if (strncmp(_header._jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) { |
0 | 474 fail_continue("The shared archive file was created by a different" |
475 " version or build of HotSpot."); | |
476 return false; | |
477 } | |
7461
561148896559
8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents:
7460
diff
changeset
|
478 if (_header._obj_alignment != ObjectAlignmentInBytes) { |
561148896559
8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents:
7460
diff
changeset
|
479 fail_continue("The shared archive file's ObjectAlignmentInBytes of %d" |
561148896559
8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents:
7460
diff
changeset
|
480 " does not equal the current ObjectAlignmentInBytes of %d.", |
561148896559
8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents:
7460
diff
changeset
|
481 _header._obj_alignment, ObjectAlignmentInBytes); |
561148896559
8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents:
7460
diff
changeset
|
482 return false; |
561148896559
8005076: Creating a CDS archive with one alignment and running another causes a crash.
hseigel
parents:
7460
diff
changeset
|
483 } |
0 | 484 |
485 // Cannot verify interpreter yet, as it can only be created after the GC | |
486 // heap has been initialized. | |
487 | |
488 if (_header._num_jars >= JVM_SHARED_JARS_MAX) { | |
489 fail_continue("Too many jar files to share."); | |
490 return false; | |
491 } | |
492 | |
493 // Build checks on classpath and jar files | |
494 int num_jars_now = 0; | |
495 ClassPathEntry *cpe = ClassLoader::classpath_entry(0); | |
496 for ( ; cpe != NULL; cpe = cpe->next()) { | |
497 | |
498 if (cpe->is_jar_file()) { | |
499 if (num_jars_now < _header._num_jars) { | |
500 | |
501 // Jar file - verify timestamp and file size. | |
502 struct stat st; | |
503 const char *path = cpe->name(); | |
504 if (os::stat(path, &st) != 0) { | |
505 fail_continue("Unable to open jar file %s.", path); | |
506 return false; | |
507 } | |
508 if (_header._jar[num_jars_now]._timestamp != st.st_mtime || | |
509 _header._jar[num_jars_now]._filesize != st.st_size) { | |
510 fail_continue("A jar file is not the one used while building" | |
511 " the shared archive file."); | |
512 return false; | |
513 } | |
514 } | |
515 ++num_jars_now; | |
516 } else { | |
517 | |
518 // If directories appear in boot classpath, they must be empty to | |
519 // avoid having to verify each individual class file. | |
520 const char* name = ((ClassPathDirEntry*)cpe)->name(); | |
521 if (!os::dir_is_empty(name)) { | |
522 fail_continue("Boot classpath directory %s is not empty.", name); | |
523 return false; | |
524 } | |
525 } | |
526 } | |
527 if (num_jars_now < _header._num_jars) { | |
528 fail_continue("The number of jar files in the boot classpath is" | |
529 " less than the number the shared archive was created with."); | |
530 return false; | |
531 } | |
532 | |
533 return true; | |
534 } | |
535 | |
536 // The following method is provided to see whether a given pointer | |
537 // falls in the mapped shared space. | |
538 // Param: | |
539 // p, The given pointer | |
540 // Return: | |
541 // True if the p is within the mapped shared space, otherwise, false. | |
542 bool FileMapInfo::is_in_shared_space(const void* p) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1980
diff
changeset
|
543 for (int i = 0; i < MetaspaceShared::n_regions; i++) { |
0 | 544 if (p >= _header._space[i]._base && |
545 p < _header._space[i]._base + _header._space[i]._used) { | |
546 return true; | |
547 } | |
548 } | |
549 | |
550 return false; | |
551 } |