comparison src/share/vm/memory/filemap.cpp @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents 828eafbd85cc
children 716c64bda5ba
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
1 /* 1 /*
2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
203 } 203 }
204 204
205 205
206 // Dump shared spaces to file. 206 // Dump shared spaces to file.
207 207
208 void FileMapInfo::write_space(int i, CompactibleSpace* space, bool read_only) { 208 void FileMapInfo::write_space(int i, Metaspace* space, bool read_only) {
209 align_file_position(); 209 align_file_position();
210 size_t used = space->used_words(Metaspace::NonClassType) * BytesPerWord;
211 size_t capacity = space->capacity_words(Metaspace::NonClassType) * BytesPerWord;
210 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; 212 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
211 write_region(i, (char*)space->bottom(), space->used(), 213 write_region(i, (char*)space->bottom(), used, capacity, read_only, false);
212 space->capacity(), read_only, false);
213 } 214 }
214 215
215 216
216 // Dump region to file. 217 // Dump region to file.
217 218
221 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[region]; 222 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[region];
222 223
223 if (_file_open) { 224 if (_file_open) {
224 guarantee(si->_file_offset == _file_offset, "file offset mismatch."); 225 guarantee(si->_file_offset == _file_offset, "file offset mismatch.");
225 if (PrintSharedSpaces) { 226 if (PrintSharedSpaces) {
226 tty->print_cr("Shared file region %d: 0x%x bytes, addr 0x%x," 227 tty->print_cr("Shared file region %d: 0x%6x bytes, addr " INTPTR_FORMAT
227 " file offset 0x%x", region, size, base, _file_offset); 228 " file offset 0x%6x", region, size, base, _file_offset);
228 } 229 }
229 } else { 230 } else {
230 si->_file_offset = _file_offset; 231 si->_file_offset = _file_offset;
231 } 232 }
232 si->_base = base; 233 si->_base = base;
295 _fd = -1; 296 _fd = -1;
296 } 297 }
297 } 298 }
298 299
299 300
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: 301 // JVM/TI RedefineClasses() support:
321 // Remap the shared readonly space to shared readwrite, private. 302 // Remap the shared readonly space to shared readwrite, private.
322 bool FileMapInfo::remap_shared_readonly_as_readwrite() { 303 bool FileMapInfo::remap_shared_readonly_as_readwrite() {
323 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0]; 304 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0];
324 if (!si->_read_only) { 305 if (!si->_read_only) {
344 } 325 }
345 si->_read_only = false; 326 si->_read_only = false;
346 return true; 327 return true;
347 } 328 }
348 329
330 // Map the whole region at once, assumed to be allocated contiguously.
331 ReservedSpace FileMapInfo::reserve_shared_memory() {
332 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0];
333 char* requested_addr = si->_base;
334 size_t alignment = os::vm_allocation_granularity();
335
336 size_t size = align_size_up(SharedReadOnlySize + SharedReadWriteSize +
337 SharedMiscDataSize + SharedMiscCodeSize,
338 alignment);
339
340 // Reserve the space first, then map otherwise map will go right over some
341 // other reserved memory (like the code cache).
342 ReservedSpace rs(size, alignment, false, requested_addr);
343 if (!rs.is_reserved()) {
344 fail_continue(err_msg("Unable to reserved shared space at required address " INTPTR_FORMAT, requested_addr));
345 return rs;
346 }
347 return rs;
348 }
349 349
350 // Memory map a region in the address space. 350 // Memory map a region in the address space.
351 351
352 char* FileMapInfo::map_region(int i, ReservedSpace rs) { 352 char* FileMapInfo::map_region(int i, ReservedSpace rs) {
353 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; 353 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
356 356
357 ReservedSpace mapped_rs = rs.first_part(size, true, true); 357 ReservedSpace mapped_rs = rs.first_part(size, true, true);
358 ReservedSpace unmapped_rs = rs.last_part(size); 358 ReservedSpace unmapped_rs = rs.last_part(size);
359 mapped_rs.release(); 359 mapped_rs.release();
360 360
361 return map_region(i, true); 361 return map_region(i);
362 } 362 }
363 363
364 364
365 // Memory map a region in the address space. 365 // Memory map a region in the address space.
366 366 static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode"};
367 char* FileMapInfo::map_region(int i, bool address_must_match) { 367
368 char* FileMapInfo::map_region(int i) {
368 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; 369 struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
369 size_t used = si->_used; 370 size_t used = si->_used;
370 size_t size = align_size_up(used, os::vm_allocation_granularity()); 371 size_t alignment = os::vm_allocation_granularity();
371 char *requested_addr = 0; 372 size_t size = align_size_up(used, alignment);
372 if (address_must_match) { 373 char *requested_addr = si->_base;
373 requested_addr = si->_base; 374
374 } 375 // map the contents of the CDS archive in this memory
375 char *base = os::map_memory(_fd, _full_path, si->_file_offset, 376 char *base = os::map_memory(_fd, _full_path, si->_file_offset,
376 requested_addr, size, si->_read_only, 377 requested_addr, size, si->_read_only,
377 si->_allow_exec); 378 si->_allow_exec);
378 if (base == NULL) { 379 if (base == NULL || base != si->_base) {
379 fail_continue("Unable to map shared space."); 380 fail_continue(err_msg("Unable to map %s shared space at required address.", shared_region_name[i]));
380 return NULL; 381 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 } 382 }
390 return base; 383 return base;
391 } 384 }
392 385
393 386
415 408
416 // Open the shared archive file, read and validate the header 409 // Open the shared archive file, read and validate the header
417 // information (version, boot classpath, etc.). If initialization 410 // information (version, boot classpath, etc.). If initialization
418 // fails, shared spaces are disabled and the file is closed. [See 411 // fails, shared spaces are disabled and the file is closed. [See
419 // fail_continue.] 412 // fail_continue.]
420
421
422 bool FileMapInfo::initialize() { 413 bool FileMapInfo::initialize() {
423 assert(UseSharedSpaces, "UseSharedSpaces expected."); 414 assert(UseSharedSpaces, "UseSharedSpaces expected.");
424 415
425 if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space()) { 416 if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space()) {
426 fail_continue("Tool agent requires sharing to be disabled."); 417 fail_continue("Tool agent requires sharing to be disabled.");
516 // Param: 507 // Param:
517 // p, The given pointer 508 // p, The given pointer
518 // Return: 509 // Return:
519 // True if the p is within the mapped shared space, otherwise, false. 510 // True if the p is within the mapped shared space, otherwise, false.
520 bool FileMapInfo::is_in_shared_space(const void* p) { 511 bool FileMapInfo::is_in_shared_space(const void* p) {
521 for (int i = 0; i < CompactingPermGenGen::n_regions; i++) { 512 for (int i = 0; i < MetaspaceShared::n_regions; i++) {
522 if (p >= _header._space[i]._base && 513 if (p >= _header._space[i]._base &&
523 p < _header._space[i]._base + _header._space[i]._used) { 514 p < _header._space[i]._base + _header._space[i]._used) {
524 return true; 515 return true;
525 } 516 }
526 } 517 }