Skip to content
Permalink
Browse files
8236847: CDS archive with 4K alignment unusable on machines with 64k …
…pages

Reviewed-by: iklam, stuefe, erikj, ihse
  • Loading branch information
yminqi committed Mar 11, 2021
1 parent 273f8bd commit 3820ab9e8247b1b5095a04b1d0bebe15ff56a394
Show file tree
Hide file tree
Showing 16 changed files with 206 additions and 59 deletions.
@@ -248,6 +248,7 @@ JDKOPT_ENABLE_DISABLE_GENERATE_CLASSLIST
JDKOPT_EXCLUDE_TRANSLATIONS
JDKOPT_ENABLE_DISABLE_MANPAGES
JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE
JDKOPT_ENABLE_DISABLE_COMPATIBLE_CDS_ALIGNMENT

###############################################################################
#
@@ -1,5 +1,5 @@
#
# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 2021, 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
@@ -585,6 +585,30 @@ AC_DEFUN([JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE],
AC_SUBST(BUILD_CDS_ARCHIVE)
])

################################################################################
#
# Enable the alternative CDS core region alignment
#
AC_DEFUN([JDKOPT_ENABLE_DISABLE_COMPATIBLE_CDS_ALIGNMENT],
[
UTIL_ARG_ENABLE(NAME: compatible-cds-alignment, DEFAULT: false,
RESULT: ENABLE_COMPATIBLE_CDS_ALIGNMENT,
DESC: [enable use alternative compatible cds core region alignment],
DEFAULT_DESC: [disabled],
CHECKING_MSG: [if compatible cds region alignment enabled],
CHECK_AVAILABLE: [
AC_MSG_CHECKING([if CDS archive is available])
if test "x$BUILD_CDS_ARCHIVE" = "xfalse"; then
AVAILABLE=false
AC_MSG_RESULT([no (CDS is disabled)])
else
AVAILABLE=true
AC_MSG_RESULT([yes])
fi
])
AC_SUBST(ENABLE_COMPATIBLE_CDS_ALIGNMENT)
])

################################################################################
#
# Disallow any output from containing absolute paths from the build system.
@@ -349,6 +349,8 @@ BUILD_MANPAGES := @BUILD_MANPAGES@

BUILD_CDS_ARCHIVE := @BUILD_CDS_ARCHIVE@

ENABLE_COMPATIBLE_CDS_ALIGNMENT := @ENABLE_COMPATIBLE_CDS_ALIGNMENT@

ALLOW_ABSOLUTE_PATHS_IN_OUTPUT := @ALLOW_ABSOLUTE_PATHS_IN_OUTPUT@

# The boot jdk to use. This is overridden in bootcycle-spec.gmk. Make sure to keep
@@ -441,6 +441,7 @@ var getJibProfilesProfiles = function (input, common, data) {
dependencies: ["devkit", "gtest", "pandoc"],
configure_args: concat(common.configure_args_64bit, "--with-zlib=system",
"--with-macosx-version-max=10.12.00",
"--enable-compatible-cds-alignment",
// Use system SetFile instead of the one in the devkit as the
// devkit one may not work on Catalina.
"SETFILE=/usr/bin/SetFile"),
@@ -477,6 +478,7 @@ var getJibProfilesProfiles = function (input, common, data) {
dependencies: ["devkit", "gtest", "build_devkit", "pandoc"],
configure_args: [
"--openjdk-target=aarch64-linux-gnu",
"--enable-compatible-cds-alignment",
],
},

@@ -1,5 +1,5 @@
#
# Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2013, 2021, 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
@@ -99,3 +99,7 @@ endif
ifneq ($(HOTSPOT_OVERRIDE_LIBPATH), )
JVM_CFLAGS += -DOVERRIDE_LIBPATH='"$(HOTSPOT_OVERRIDE_LIBPATH)"'
endif

ifeq ($(ENABLE_COMPATIBLE_CDS_ALIGNMENT), true)
JVM_CFLAGS += -DCOMPATIBLE_CDS_ALIGNMENT
endif
@@ -25,6 +25,12 @@
#ifndef OS_CPU_BSD_X86_OS_BSD_X86_HPP
#define OS_CPU_BSD_X86_OS_BSD_X86_HPP

// Core region alignment is 16K to be able to run binaries built on MacOS x64
// on MacOS aarch64.
#if defined(__APPLE__) && defined(COMPATIBLE_CDS_ALIGNMENT)
#define CDS_CORE_REGION_ALIGNMENT (16*K)
#endif

static void setup_fpu();
static bool supports_sse();
static juint cpu_microcode_revision();
@@ -26,6 +26,10 @@
#ifndef OS_CPU_LINUX_AARCH64_OS_LINUX_AARCH64_HPP
#define OS_CPU_LINUX_AARCH64_OS_LINUX_AARCH64_HPP

#if defined(COMPATIBLE_CDS_ALIGNMENT)
#define CDS_CORE_REGION_ALIGNMENT (64*K)
#endif

static void setup_fpu();

static bool is_allocatable(size_t bytes);
@@ -327,19 +327,19 @@ size_t ArchiveBuilder::estimate_archive_size() {
total += _estimated_hashtable_bytes;

// allow fragmentation at the end of each dump region
total += _total_dump_regions * reserve_alignment();
total += _total_dump_regions * MetaspaceShared::core_region_alignment();

log_info(cds)("_estimated_hashtable_bytes = " SIZE_FORMAT " + " SIZE_FORMAT " = " SIZE_FORMAT,
symbol_table_est, dictionary_est, _estimated_hashtable_bytes);
log_info(cds)("_estimated_metaspaceobj_bytes = " SIZE_FORMAT, _estimated_metaspaceobj_bytes);
log_info(cds)("total estimate bytes = " SIZE_FORMAT, total);

return align_up(total, reserve_alignment());
return align_up(total, MetaspaceShared::core_region_alignment());
}

address ArchiveBuilder::reserve_buffer() {
size_t buffer_size = estimate_archive_size();
ReservedSpace rs(buffer_size);
ReservedSpace rs(buffer_size, MetaspaceShared::core_region_alignment(), false);
if (!rs.is_reserved()) {
log_error(cds)("Failed to reserve " SIZE_FORMAT " bytes of output buffer.", buffer_size);
vm_direct_exit(0);
@@ -377,7 +377,7 @@ address ArchiveBuilder::reserve_buffer() {

// At run time, we will mmap the dynamic archive at my_archive_requested_bottom
_requested_static_archive_top = _requested_static_archive_bottom + static_archive_size;
my_archive_requested_bottom = align_up(_requested_static_archive_top, MetaspaceShared::reserved_space_alignment());
my_archive_requested_bottom = align_up(_requested_static_archive_top, MetaspaceShared::core_region_alignment());

_requested_dynamic_archive_bottom = my_archive_requested_bottom;
}
@@ -223,9 +223,8 @@ class ArchiveBuilder : public StackObj {
static ArchiveBuilder* _current;

public:
// Use this when you allocate space with MetaspaceShare::read_only_space_alloc()
// outside of ArchiveBuilder::dump_{rw,ro}_region. These are usually for misc tables
// that are allocated in the RO space.
// Use this when you allocate space outside of ArchiveBuilder::dump_{rw,ro}_region.
// These are usually for misc tables that are allocated in the RO space.
class OtherROAllocMark {
char* _oldtop;
public:
@@ -265,10 +264,6 @@ class ArchiveBuilder : public StackObj {

size_t estimate_archive_size();

static size_t reserve_alignment() {
return os::vm_allocation_granularity();
}

void start_dump_space(DumpRegion* next);
void verify_estimate_size(size_t estimate, const char* which);

@@ -246,7 +246,7 @@ void DumpRegion::init(ReservedSpace* rs, VirtualSpace* vs) {

void DumpRegion::pack(DumpRegion* next) {
assert(!is_packed(), "sanity");
_end = (char*)align_up(_top, MetaspaceShared::reserved_space_alignment());
_end = (char*)align_up(_top, MetaspaceShared::core_region_alignment());
_is_packed = true;
if (next != NULL) {
next->_rs = _rs;
@@ -47,12 +47,6 @@


class DynamicArchiveBuilder : public ArchiveBuilder {
public:

static size_t reserve_alignment() {
return os::vm_allocation_granularity();
}

public:
void mark_pointer(address* ptr_loc) {
ArchivePtrMarker::mark_pointer(ptr_loc);
@@ -179,7 +173,7 @@ void DynamicArchiveBuilder::init_header() {
for (int i = 0; i < MetaspaceShared::n_regions; i++) {
_header->set_base_region_crc(i, base_info->space_crc(i));
}
_header->populate(base_info, os::vm_allocation_granularity());
_header->populate(base_info, base_info->core_region_alignment());
}

void DynamicArchiveBuilder::release_header() {
@@ -198,18 +198,18 @@ FileMapInfo::~FileMapInfo() {
}
}

void FileMapInfo::populate_header(size_t alignment) {
header()->populate(this, alignment);
void FileMapInfo::populate_header(size_t core_region_alignment) {
header()->populate(this, core_region_alignment);
}

void FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
void FileMapHeader::populate(FileMapInfo* mapinfo, size_t core_region_alignment) {
if (DynamicDumpSharedSpaces) {
_magic = CDS_DYNAMIC_ARCHIVE_MAGIC;
} else {
_magic = CDS_ARCHIVE_MAGIC;
}
_version = CURRENT_CDS_ARCHIVE_VERSION;
_alignment = alignment;
_core_region_alignment = core_region_alignment;
_obj_alignment = ObjectAlignmentInBytes;
_compact_strings = CompactStrings;
if (HeapShared::is_heap_object_archiving_allowed()) {
@@ -267,7 +267,7 @@ void FileMapHeader::print(outputStream* st) {
st->print_cr("============ end regions ======== ");

st->print_cr("- header_size: " SIZE_FORMAT, _header_size);
st->print_cr("- alignment: " SIZE_FORMAT, _alignment);
st->print_cr("- core_region_alignment: " SIZE_FORMAT, _core_region_alignment);
st->print_cr("- obj_alignment: %d", _obj_alignment);
st->print_cr("- narrow_oop_base: " INTPTR_FORMAT, p2i(_narrow_oop_base));
st->print_cr("- narrow_oop_base: " INTPTR_FORMAT, p2i(_narrow_oop_base));
@@ -1225,7 +1225,7 @@ void FileMapInfo::open_for_write(const char* path) {
header_bytes += strlen(Arguments::GetSharedArchivePath()) + 1;
}

header_bytes = align_up(header_bytes, os::vm_allocation_granularity());
header_bytes = align_up(header_bytes, MetaspaceShared::core_region_alignment());
_file_offset = header_bytes;
seek_to_position(_file_offset);
}
@@ -1251,7 +1251,7 @@ void FileMapInfo::write_header() {
}

size_t FileMapRegion::used_aligned() const {
return align_up(used(), os::vm_allocation_granularity());
return align_up(used(), MetaspaceShared::core_region_alignment());
}

void FileMapRegion::init(int region_index, size_t mapping_offset, size_t size, bool read_only,
@@ -1456,15 +1456,15 @@ void FileMapInfo::write_bytes(const void* buffer, size_t nbytes) {

bool FileMapInfo::is_file_position_aligned() const {
return _file_offset == align_up(_file_offset,
os::vm_allocation_granularity());
MetaspaceShared::core_region_alignment());
}

// Align file position to an allocation unit boundary.

void FileMapInfo::align_file_position() {
assert(_file_open, "must be");
size_t new_file_offset = align_up(_file_offset,
os::vm_allocation_granularity());
MetaspaceShared::core_region_alignment());
if (new_file_offset != _file_offset) {
_file_offset = new_file_offset;
// Seek one byte back from the target and write a byte to insure
@@ -1507,8 +1507,7 @@ bool FileMapInfo::remap_shared_readonly_as_readwrite() {
// the space is already readwrite so we are done
return true;
}
size_t used = si->used();
size_t size = align_up(used, os::vm_allocation_granularity());
size_t size = si->used_aligned();
if (!open_for_read()) {
return false;
}
@@ -2088,8 +2087,7 @@ void FileMapInfo::unmap_region(int i) {
assert(!HeapShared::is_heap_region(i), "sanity");
FileMapRegion* si = space_at(i);
char* mapped_base = si->mapped_base();
size_t used = si->used();
size_t size = align_up(used, os::vm_allocation_granularity());
size_t size = si->used_aligned();

if (mapped_base != NULL) {
if (size > 0 && si->mapped_from_file()) {
@@ -154,7 +154,7 @@ class FileMapRegion: private CDSFileMapRegion {
size_t mapping_offset() const { return _mapping_offset; }
size_t mapping_end_offset() const { return _mapping_offset + used_aligned(); }
size_t used() const { return _used; }
size_t used_aligned() const; // aligned up to os::vm_allocation_granularity()
size_t used_aligned() const; // aligned up to MetaspaceShared::core_region_alignment()
char* mapped_base() const { assert_is_not_heap_region(); return _mapped_base; }
char* mapped_end() const { return mapped_base() + used_aligned(); }
bool read_only() const { return _read_only != 0; }
@@ -187,7 +187,7 @@ class FileMapHeader: private CDSFileMapHeaderBase {
// The following fields record the states of the VM during dump time.
// They are compared with the runtime states to see if the archive
// can be used.
size_t _alignment; // how shared archive should be aligned
size_t _core_region_alignment; // how shared archive should be aligned
int _obj_alignment; // value of ObjectAlignmentInBytes
address _narrow_oop_base; // compressed oop encoding base
int _narrow_oop_shift; // compressed oop encoding shift
@@ -251,7 +251,7 @@ class FileMapHeader: private CDSFileMapHeaderBase {
// Accessors -- fields declared in FileMapHeader

size_t header_size() const { return _header_size; }
size_t alignment() const { return _alignment; }
size_t core_region_alignment() const { return _core_region_alignment; }
int obj_alignment() const { return _obj_alignment; }
address narrow_oop_base() const { return _narrow_oop_base; }
int narrow_oop_shift() const { return _narrow_oop_shift; }
@@ -312,7 +312,7 @@ class FileMapHeader: private CDSFileMapHeaderBase {
return FileMapRegion::cast(&_space[i]);
}

void populate(FileMapInfo* info, size_t alignment);
void populate(FileMapInfo* info, size_t core_region_alignment);

static bool is_valid_region(int region) {
return (0 <= region && region < NUM_CDS_REGIONS);
@@ -378,17 +378,17 @@ class FileMapInfo : public CHeapObj<mtInternal> {
int compute_header_crc() const { return header()->compute_crc(); }
void set_header_crc(int crc) { header()->set_crc(crc); }
int space_crc(int i) const { return space_at(i)->crc(); }
void populate_header(size_t alignment);
void populate_header(size_t core_region_alignment);
bool validate_header();
void invalidate();
int crc() const { return header()->crc(); }
int version() const { return header()->version(); }
size_t alignment() const { return header()->alignment(); }
address narrow_oop_base() const { return header()->narrow_oop_base(); }
int narrow_oop_shift() const { return header()->narrow_oop_shift(); }
uintx max_heap_size() const { return header()->max_heap_size(); }
address narrow_klass_base() const { return header()->narrow_klass_base(); }
int narrow_klass_shift() const { return header()->narrow_klass_shift(); }
size_t core_region_alignment() const { return header()->core_region_alignment(); }

CompressedOops::Mode narrow_oop_mode() const { return header()->narrow_oop_mode(); }
jshort app_module_paths_start_index() const { return header()->app_module_paths_start_index(); }

0 comments on commit 3820ab9

Please sign in to comment.