mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8243506: SharedBaseAddress is ignored by -Xshare:dump
Reviewed-by: stuefe, ccheung
This commit is contained in:
parent
b5775c831d
commit
f39a71cafe
10 changed files with 199 additions and 49 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -31,6 +31,7 @@
|
|||
#include "memory/heapShared.inline.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/metaspaceShared.hpp"
|
||||
#include "runtime/globals.hpp"
|
||||
#include "runtime/vmThread.hpp"
|
||||
#include "utilities/numberSeq.hpp"
|
||||
#include <sys/stat.h>
|
||||
|
@ -212,11 +213,13 @@ size_t SimpleCompactHashtable::calculate_header_size() {
|
|||
void SimpleCompactHashtable::serialize_header(SerializeClosure* soc) {
|
||||
// NOTE: if you change this function, you MUST change the number 5 in
|
||||
// calculate_header_size() accordingly.
|
||||
soc->do_ptr((void**)&_base_address);
|
||||
soc->do_u4(&_entry_count);
|
||||
soc->do_u4(&_bucket_count);
|
||||
soc->do_ptr((void**)&_buckets);
|
||||
soc->do_ptr((void**)&_entries);
|
||||
if (soc->reading()) {
|
||||
_base_address = (address)SharedBaseAddress;
|
||||
}
|
||||
}
|
||||
#endif // INCLUDE_CDS
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -58,6 +58,12 @@ void ArchivePtrMarker::mark_pointer(address* ptr_loc) {
|
|||
|
||||
if (_ptr_base <= ptr_loc && ptr_loc < _ptr_end) {
|
||||
address value = *ptr_loc;
|
||||
// We don't want any pointer that points to very bottom of the archive, otherwise when
|
||||
// MetaspaceShared::default_base_address()==0, we can't distinguish between a pointer
|
||||
// to nothing (NULL) vs a pointer to an objects that happens to be at the very bottom
|
||||
// of the archive.
|
||||
assert(value != (address)_ptr_base, "don't point to the bottom of the archive");
|
||||
|
||||
if (value != NULL) {
|
||||
assert(uintx(ptr_loc) % sizeof(intptr_t) == 0, "pointers must be stored in aligned addresses");
|
||||
size_t idx = ptr_loc - _ptr_base;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -52,6 +52,7 @@ inline bool SharedDataRelocator<COMPACTING>::do_bit(size_t offset) {
|
|||
}
|
||||
|
||||
address new_ptr = old_ptr + _delta;
|
||||
assert(new_ptr != NULL, "don't point to the bottom of the archive"); // See ArchivePtrMarker::mark_pointer().
|
||||
assert(_valid_new_base <= new_ptr && new_ptr < _valid_new_end, "must be");
|
||||
|
||||
DEBUG_ONLY(log_trace(cds, reloc)("Patch2: @%8d [" PTR_FORMAT "] " PTR_FORMAT " -> " PTR_FORMAT,
|
||||
|
|
|
@ -966,13 +966,13 @@ void DynamicArchiveBuilder::relocate_buffer_to_target() {
|
|||
if (addr_delta == 0) {
|
||||
ArchivePtrMarker::compact(relocatable_base, relocatable_end);
|
||||
} else {
|
||||
// The base archive is NOT mapped at Arguments::default_SharedBaseAddress() (due to ASLR).
|
||||
// The base archive is NOT mapped at MetaspaceShared::requested_base_address() (due to ASLR).
|
||||
// This means that the current content of the dynamic archive is based on a random
|
||||
// address. Let's relocate all the pointers, so that it can be mapped to
|
||||
// Arguments::default_SharedBaseAddress() without runtime relocation.
|
||||
// MetaspaceShared::requested_base_address() without runtime relocation.
|
||||
//
|
||||
// Note: both the base and dynamic archive are written with
|
||||
// FileMapHeader::_shared_base_address == Arguments::default_SharedBaseAddress()
|
||||
// FileMapHeader::_requested_base_address == MetaspaceShared::requested_base_address()
|
||||
|
||||
// Patch all pointers that are marked by ptrmap within this region,
|
||||
// where we have just dumped all the metaspace data.
|
||||
|
@ -992,7 +992,7 @@ void DynamicArchiveBuilder::relocate_buffer_to_target() {
|
|||
|
||||
// after patching, the pointers must point inside this range
|
||||
// (the requested location of the archive, as mapped at runtime).
|
||||
address valid_new_base = (address)Arguments::default_SharedBaseAddress();
|
||||
address valid_new_base = (address)MetaspaceShared::requested_base_address();
|
||||
address valid_new_end = valid_new_base + base_plus_top_size;
|
||||
|
||||
log_debug(cds)("Relocating archive from [" INTPTR_FORMAT " - " INTPTR_FORMAT "] to "
|
||||
|
@ -1020,7 +1020,7 @@ void DynamicArchiveBuilder::write_archive(char* serialized_data) {
|
|||
const char* archive_name = Arguments::GetSharedDynamicArchivePath();
|
||||
dynamic_info->open_for_write(archive_name);
|
||||
MetaspaceShared::write_core_archive_regions(dynamic_info, NULL, NULL);
|
||||
dynamic_info->set_final_requested_base((char*)Arguments::default_SharedBaseAddress());
|
||||
dynamic_info->set_final_requested_base((char*)MetaspaceShared::requested_base_address());
|
||||
dynamic_info->set_header_crc(dynamic_info->compute_header_crc());
|
||||
dynamic_info->write_header();
|
||||
dynamic_info->close();
|
||||
|
|
|
@ -88,6 +88,7 @@ address MetaspaceShared::_i2i_entry_code_buffers = NULL;
|
|||
size_t MetaspaceShared::_i2i_entry_code_buffers_size = 0;
|
||||
void* MetaspaceShared::_shared_metaspace_static_top = NULL;
|
||||
intx MetaspaceShared::_relocation_delta;
|
||||
char* MetaspaceShared::_requested_base_address;
|
||||
|
||||
// The CDS archive is divided into the following regions:
|
||||
// mc - misc code (the method entry trampolines, c++ vtables)
|
||||
|
@ -240,33 +241,53 @@ char* MetaspaceShared::read_only_space_alloc(size_t num_bytes) {
|
|||
|
||||
size_t MetaspaceShared::reserved_space_alignment() { return os::vm_allocation_granularity(); }
|
||||
|
||||
static bool shared_base_valid(char* shared_base) {
|
||||
#ifdef _LP64
|
||||
// Check SharedBaseAddress for validity. At this point, os::init() must
|
||||
// have been ran.
|
||||
static void check_SharedBaseAddress() {
|
||||
SharedBaseAddress = align_up(SharedBaseAddress,
|
||||
MetaspaceShared::reserved_space_alignment());
|
||||
if (!CompressedKlassPointers::is_valid_base((address)SharedBaseAddress)) {
|
||||
log_warning(cds)("SharedBaseAddress=" PTR_FORMAT " is invalid for this "
|
||||
"platform, option will be ignored.",
|
||||
p2i((address)SharedBaseAddress));
|
||||
SharedBaseAddress = Arguments::default_SharedBaseAddress();
|
||||
}
|
||||
}
|
||||
return CompressedKlassPointers::is_valid_base((address)shared_base);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool shared_base_too_high(char* shared_base, size_t cds_total) {
|
||||
if (SharedBaseAddress != 0 && shared_base < (char*)SharedBaseAddress) {
|
||||
// SharedBaseAddress is very high (e.g., 0xffffffffffffff00) so
|
||||
// align_up(SharedBaseAddress, MetaspaceShared::reserved_space_alignment()) has wrapped around.
|
||||
return true;
|
||||
}
|
||||
if (max_uintx - uintx(shared_base) < uintx(cds_total)) {
|
||||
// The end of the archive will wrap around
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static char* compute_shared_base(size_t cds_total) {
|
||||
char* shared_base = (char*)align_up((char*)SharedBaseAddress, MetaspaceShared::reserved_space_alignment());
|
||||
const char* err = NULL;
|
||||
if (shared_base_too_high(shared_base, cds_total)) {
|
||||
err = "too high";
|
||||
} else if (!shared_base_valid(shared_base)) {
|
||||
err = "invalid for this platform";
|
||||
}
|
||||
if (err) {
|
||||
log_warning(cds)("SharedBaseAddress (" INTPTR_FORMAT ") is %s. Reverted to " INTPTR_FORMAT,
|
||||
p2i((void*)SharedBaseAddress), err,
|
||||
p2i((void*)Arguments::default_SharedBaseAddress()));
|
||||
SharedBaseAddress = Arguments::default_SharedBaseAddress();
|
||||
shared_base = (char*)align_up((char*)SharedBaseAddress, MetaspaceShared::reserved_space_alignment());
|
||||
}
|
||||
assert(!shared_base_too_high(shared_base, cds_total) && shared_base_valid(shared_base), "Sanity");
|
||||
return shared_base;
|
||||
}
|
||||
|
||||
void MetaspaceShared::initialize_dumptime_shared_and_meta_spaces() {
|
||||
assert(DumpSharedSpaces, "should be called for dump time only");
|
||||
|
||||
#ifdef _LP64
|
||||
check_SharedBaseAddress();
|
||||
#endif
|
||||
|
||||
const size_t reserve_alignment = MetaspaceShared::reserved_space_alignment();
|
||||
char* shared_base = (char*)align_up((char*)SharedBaseAddress, reserve_alignment);
|
||||
|
||||
#ifdef _LP64
|
||||
assert(CompressedKlassPointers::is_valid_base((address)shared_base), "Sanity");
|
||||
// On 64-bit VM we reserve a 4G range and, if UseCompressedClassPointers=1,
|
||||
// will use that to house both the archives and the ccs. See below for
|
||||
// details.
|
||||
|
@ -278,6 +299,9 @@ void MetaspaceShared::initialize_dumptime_shared_and_meta_spaces() {
|
|||
size_t cds_total = align_down(256*M, reserve_alignment);
|
||||
#endif
|
||||
|
||||
char* shared_base = compute_shared_base(cds_total);
|
||||
_requested_base_address = shared_base;
|
||||
|
||||
// Whether to use SharedBaseAddress as attach address.
|
||||
bool use_requested_base = true;
|
||||
|
||||
|
@ -398,6 +422,10 @@ void MetaspaceShared::initialize_dumptime_shared_and_meta_spaces() {
|
|||
log_info(cds)("Allocated shared space: " SIZE_FORMAT " bytes at " PTR_FORMAT,
|
||||
_shared_rs.size(), p2i(_shared_rs.base()));
|
||||
|
||||
// We don't want any valid object to be at the very bottom of the archive.
|
||||
// See ArchivePtrMarker::mark_pointer().
|
||||
MetaspaceShared::misc_code_space_alloc(16);
|
||||
|
||||
size_t symbol_rs_size = LP64_ONLY(3 * G) NOT_LP64(128 * M);
|
||||
_symbol_rs = ReservedSpace(symbol_rs_size);
|
||||
if (!_symbol_rs.is_reserved()) {
|
||||
|
@ -1200,7 +1228,7 @@ private:
|
|||
void print_bitmap_region_stats(size_t size, size_t total_size);
|
||||
void print_heap_region_stats(GrowableArray<MemRegion> *heap_mem,
|
||||
const char *name, size_t total_size);
|
||||
void relocate_to_default_base_address(CHeapBitMap* ptrmap);
|
||||
void relocate_to_requested_base_address(CHeapBitMap* ptrmap);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -1568,18 +1596,18 @@ void VM_PopulateDumpSharedSpace::print_class_stats() {
|
|||
}
|
||||
}
|
||||
|
||||
void VM_PopulateDumpSharedSpace::relocate_to_default_base_address(CHeapBitMap* ptrmap) {
|
||||
void VM_PopulateDumpSharedSpace::relocate_to_requested_base_address(CHeapBitMap* ptrmap) {
|
||||
intx addr_delta = MetaspaceShared::final_delta();
|
||||
if (addr_delta == 0) {
|
||||
ArchivePtrMarker::compact((address)SharedBaseAddress, (address)_ro_region.top());
|
||||
} else {
|
||||
// We are not able to reserve space at Arguments::default_SharedBaseAddress() (due to ASLR).
|
||||
// We are not able to reserve space at MetaspaceShared::requested_base_address() (due to ASLR).
|
||||
// This means that the current content of the archive is based on a random
|
||||
// address. Let's relocate all the pointers, so that it can be mapped to
|
||||
// Arguments::default_SharedBaseAddress() without runtime relocation.
|
||||
// MetaspaceShared::requested_base_address() without runtime relocation.
|
||||
//
|
||||
// Note: both the base and dynamic archive are written with
|
||||
// FileMapHeader::_shared_base_address == Arguments::default_SharedBaseAddress()
|
||||
// FileMapHeader::_requested_base_address == MetaspaceShared::requested_base_address()
|
||||
|
||||
// Patch all pointers that are marked by ptrmap within this region,
|
||||
// where we have just dumped all the metaspace data.
|
||||
|
@ -1594,7 +1622,7 @@ void VM_PopulateDumpSharedSpace::relocate_to_default_base_address(CHeapBitMap* p
|
|||
|
||||
// after patching, the pointers must point inside this range
|
||||
// (the requested location of the archive, as mapped at runtime).
|
||||
address valid_new_base = (address)Arguments::default_SharedBaseAddress();
|
||||
address valid_new_base = (address)MetaspaceShared::requested_base_address();
|
||||
address valid_new_end = valid_new_base + size;
|
||||
|
||||
log_debug(cds)("Relocating archive from [" INTPTR_FORMAT " - " INTPTR_FORMAT " ] to "
|
||||
|
@ -1681,9 +1709,9 @@ void VM_PopulateDumpSharedSpace::doit() {
|
|||
memset(MetaspaceShared::i2i_entry_code_buffers(), 0,
|
||||
MetaspaceShared::i2i_entry_code_buffers_size());
|
||||
|
||||
// relocate the data so that it can be mapped to Arguments::default_SharedBaseAddress()
|
||||
// relocate the data so that it can be mapped to MetaspaceShared::requested_base_address()
|
||||
// without runtime relocation.
|
||||
relocate_to_default_base_address(&ptrmap);
|
||||
relocate_to_requested_base_address(&ptrmap);
|
||||
|
||||
// Create and write the archive file that maps the shared spaces.
|
||||
|
||||
|
@ -1706,7 +1734,7 @@ void VM_PopulateDumpSharedSpace::doit() {
|
|||
MetaspaceShared::first_open_archive_heap_region,
|
||||
MetaspaceShared::max_open_archive_heap_region);
|
||||
|
||||
mapinfo->set_final_requested_base((char*)Arguments::default_SharedBaseAddress());
|
||||
mapinfo->set_final_requested_base((char*)MetaspaceShared::requested_base_address());
|
||||
mapinfo->set_header_crc(mapinfo->compute_header_crc());
|
||||
mapinfo->write_header();
|
||||
print_region_stats(mapinfo);
|
||||
|
@ -2162,6 +2190,7 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() {
|
|||
} else {
|
||||
FileMapInfo::set_shared_path_table(static_mapinfo);
|
||||
}
|
||||
_requested_base_address = static_mapinfo->requested_base_address();
|
||||
} else {
|
||||
set_shared_metaspace_range(NULL, NULL, NULL);
|
||||
UseSharedSpaces = false;
|
||||
|
@ -2209,6 +2238,11 @@ FileMapInfo* MetaspaceShared::open_dynamic_archive() {
|
|||
// false = map at an alternative address picked by OS.
|
||||
MapArchiveResult MetaspaceShared::map_archives(FileMapInfo* static_mapinfo, FileMapInfo* dynamic_mapinfo,
|
||||
bool use_requested_addr) {
|
||||
if (use_requested_addr && static_mapinfo->requested_base_address() == NULL) {
|
||||
log_info(cds)("Archive(s) were created with -XX:SharedBaseAddress=0. Always map at os-selected address.");
|
||||
return MAP_ARCHIVE_MMAP_FAILURE;
|
||||
}
|
||||
|
||||
PRODUCT_ONLY(if (ArchiveRelocationMode == 1 && use_requested_addr) {
|
||||
// For product build only -- this is for benchmarking the cost of doing relocation.
|
||||
// For debug builds, the check is done below, after reserving the space, for better test coverage
|
||||
|
@ -2660,11 +2694,11 @@ void MetaspaceShared::report_out_of_space(const char* name, size_t needed_bytes)
|
|||
"Please reduce the number of shared classes.");
|
||||
}
|
||||
|
||||
// This is used to relocate the pointers so that the archive can be mapped at
|
||||
// Arguments::default_SharedBaseAddress() without runtime relocation.
|
||||
// This is used to relocate the pointers so that the base archive can be mapped at
|
||||
// MetaspaceShared::requested_base_address() without runtime relocation.
|
||||
intx MetaspaceShared::final_delta() {
|
||||
return intx(Arguments::default_SharedBaseAddress()) // We want the archive to be mapped to here at runtime
|
||||
- intx(SharedBaseAddress); // .. but the archive is mapped at here at dump time
|
||||
return intx(MetaspaceShared::requested_base_address()) // We want the base archive to be mapped to here at runtime
|
||||
- intx(SharedBaseAddress); // .. but the base archive is mapped at here at dump time
|
||||
}
|
||||
|
||||
void MetaspaceShared::print_on(outputStream* st) {
|
||||
|
|
|
@ -183,6 +183,7 @@ class MetaspaceShared : AllStatic {
|
|||
static size_t _core_spaces_size;
|
||||
static void* _shared_metaspace_static_top;
|
||||
static intx _relocation_delta;
|
||||
static char* _requested_base_address;
|
||||
public:
|
||||
enum {
|
||||
// core archive spaces
|
||||
|
@ -353,6 +354,12 @@ class MetaspaceShared : AllStatic {
|
|||
static intptr_t* fix_cpp_vtable_for_dynamic_archive(MetaspaceObj::Type msotype, address obj);
|
||||
static void initialize_ptr_marker(CHeapBitMap* ptrmap);
|
||||
|
||||
// This is the base address as specified by -XX:SharedBaseAddress during -Xshare:dump.
|
||||
// Both the base/top archives are written using this as their base address.
|
||||
static char* requested_base_address() {
|
||||
return _requested_base_address;
|
||||
}
|
||||
|
||||
// Non-zero if the archive(s) need to be mapped a non-default location due to ASLR.
|
||||
static intx relocation_delta() { return _relocation_delta; }
|
||||
static intx final_delta();
|
||||
|
|
|
@ -85,7 +85,7 @@ bool Arguments::_BackgroundCompilation = BackgroundCompilation;
|
|||
bool Arguments::_ClipInlining = ClipInlining;
|
||||
intx Arguments::_Tier3InvokeNotifyFreqLog = Tier3InvokeNotifyFreqLog;
|
||||
intx Arguments::_Tier4InvocationThreshold = Tier4InvocationThreshold;
|
||||
size_t Arguments::_SharedBaseAddress = SharedBaseAddress;
|
||||
size_t Arguments::_default_SharedBaseAddress = SharedBaseAddress;
|
||||
|
||||
bool Arguments::_enable_preview = false;
|
||||
|
||||
|
@ -2281,8 +2281,8 @@ jint Arguments::parse_vm_init_args(const JavaVMInitArgs *vm_options_args,
|
|||
Arguments::_Tier4InvocationThreshold = Tier4InvocationThreshold;
|
||||
}
|
||||
|
||||
// CDS dumping always write the archive to the default value of SharedBaseAddress.
|
||||
Arguments::_SharedBaseAddress = SharedBaseAddress;
|
||||
// Remember the default value of SharedBaseAddress.
|
||||
Arguments::_default_SharedBaseAddress = SharedBaseAddress;
|
||||
|
||||
// Setup flags for mixed which is the default
|
||||
set_mode_flags(_mixed);
|
||||
|
|
|
@ -489,7 +489,7 @@ class Arguments : AllStatic {
|
|||
|
||||
static char* SharedArchivePath;
|
||||
static char* SharedDynamicArchivePath;
|
||||
static size_t _SharedBaseAddress; // The default value specified in globals.hpp
|
||||
static size_t _default_SharedBaseAddress; // The default value specified in globals.hpp
|
||||
static int num_archives(const char* archive_path) NOT_CDS_RETURN_(0);
|
||||
static void extract_shared_archive_paths(const char* archive_path,
|
||||
char** base_archive_path,
|
||||
|
@ -572,7 +572,7 @@ class Arguments : AllStatic {
|
|||
|
||||
static const char* GetSharedArchivePath() { return SharedArchivePath; }
|
||||
static const char* GetSharedDynamicArchivePath() { return SharedDynamicArchivePath; }
|
||||
static size_t default_SharedBaseAddress() { return _SharedBaseAddress; }
|
||||
static size_t default_SharedBaseAddress() { return _default_SharedBaseAddress; }
|
||||
// Java launcher properties
|
||||
static void process_sun_java_launcher_properties(JavaVMInitArgs* args);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -40,7 +40,13 @@ public class SharedBaseAddress {
|
|||
private static final String[] testTable = {
|
||||
"1g", "8g", "64g","512g", "4t",
|
||||
"32t", "128t", "0",
|
||||
"1", "64k", "64M"
|
||||
"1", "64k", "64M",
|
||||
"0xfffffffffff00000", // archive top wraps around 64-bit address space
|
||||
"0xfff80000", // archive top wraps around 32-bit address space
|
||||
"0xffffffffffffffff", // archive bottom wraps around 64-bit address space -- due to align_up()
|
||||
"0xffffffff", // archive bottom wraps around 32-bit address space -- due to align_up()
|
||||
"0x00007ffffff00000", // end of archive will go past the end of user space on linux/x64
|
||||
"0", // always let OS pick the base address at runtime (ASLR for CDS archive)
|
||||
};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
@ -50,10 +56,16 @@ public class SharedBaseAddress {
|
|||
System.out.println("sharedBaseAddress = " + testEntry);
|
||||
CDSOptions opts = (new CDSOptions())
|
||||
.setArchiveName(filename)
|
||||
.addPrefix("-XX:SharedBaseAddress=" + testEntry);
|
||||
.addPrefix("-XX:SharedBaseAddress=" + testEntry)
|
||||
.addPrefix("-Xlog:cds=debug")
|
||||
.addPrefix("-Xlog:cds+reloc=debug");
|
||||
|
||||
CDSTestUtils.createArchiveAndCheck(opts);
|
||||
CDSTestUtils.runWithArchiveAndCheck(opts);
|
||||
OutputAnalyzer out = CDSTestUtils.runWithArchiveAndCheck(opts);
|
||||
if (testEntry.equals("0")) {
|
||||
out.shouldContain("Archive(s) were created with -XX:SharedBaseAddress=0. Always map at os-selected address.")
|
||||
.shouldContain("Try to map archive(s) at an alternative address");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test how the dynamic archive handles -XX:SharedBaseAddress
|
||||
* @requires vm.cds
|
||||
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes
|
||||
* @build Hello
|
||||
* @build sun.hotspot.WhiteBox
|
||||
* @run driver ClassFileInstaller -jar hello.jar Hello
|
||||
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. SharedBaseAddressOption
|
||||
*/
|
||||
|
||||
import jdk.test.lib.Platform;
|
||||
|
||||
public class SharedBaseAddressOption extends DynamicArchiveTestBase {
|
||||
static String appJar = ClassFileInstaller.getJarPath("hello.jar");
|
||||
static String mainClass = "Hello";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
runTest(SharedBaseAddressOption::testCustomBase);
|
||||
}
|
||||
|
||||
static void testCustomBase() throws Exception {
|
||||
|
||||
// (1) -XX:SharedBaseAddress=0 -- the archives will always be relocated at runtime
|
||||
doTest("0");
|
||||
|
||||
// (2) -XX:SharedBaseAddress=0x810000000
|
||||
if (Platform.is64bit()) {
|
||||
doTest("0x810000000");
|
||||
}
|
||||
|
||||
// (3) -XX:SharedBaseAddress that's so high that the archive may wrap around 64-bit
|
||||
if (Platform.is64bit()) {
|
||||
doTest("0xfffffffffff00000");
|
||||
}
|
||||
}
|
||||
|
||||
static void doTest(String sharedBase) throws Exception {
|
||||
String baseArchiveName = getNewArchiveName("base");
|
||||
String topArchiveName = getNewArchiveName("top");
|
||||
|
||||
TestCommon.dumpBaseArchive(baseArchiveName, "-XX:SharedBaseAddress=" + sharedBase,
|
||||
"-Xlog:cds=debug",
|
||||
"-Xlog:cds+reloc=debug",
|
||||
"-Xlog:cds+dynamic=debug");
|
||||
|
||||
dump2(baseArchiveName, topArchiveName,
|
||||
"-Xlog:cds=debug",
|
||||
"-Xlog:cds+reloc=debug",
|
||||
"-Xlog:cds+dynamic=debug",
|
||||
"-cp", appJar, mainClass)
|
||||
.assertNormalExit();
|
||||
|
||||
// a top archive specified in the base archive position
|
||||
run2(baseArchiveName, topArchiveName,
|
||||
"-Xlog:cds=debug",
|
||||
"-Xlog:cds+reloc=debug",
|
||||
"-Xlog:cds+dynamic=debug",
|
||||
"-cp", appJar, mainClass)
|
||||
.assertNormalExit();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue