From ac05bc8605bcf343f0c230868af3056f03461e01 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Fri, 2 Sep 2022 23:47:48 +0000 Subject: [PATCH] 8293293: Move archive heap loading code out of heapShared.cpp Reviewed-by: erikj, coleenp --- make/hotspot/lib/JvmFeatures.gmk | 4 - src/hotspot/share/cds/archiveHeapLoader.cpp | 437 ++++++++++++++++++ src/hotspot/share/cds/archiveHeapLoader.hpp | 170 +++++++ ...nline.hpp => archiveHeapLoader.inline.hpp} | 13 +- src/hotspot/share/cds/archiveUtils.cpp | 15 +- src/hotspot/share/cds/filemap.cpp | 27 +- src/hotspot/share/cds/heapShared.cpp | 408 +--------------- src/hotspot/share/cds/heapShared.hpp | 106 +---- src/hotspot/share/cds/metaspaceShared.cpp | 5 +- .../share/classfile/compactHashtable.cpp | 1 - src/hotspot/share/classfile/javaClasses.cpp | 8 +- src/hotspot/share/classfile/stringTable.cpp | 11 +- .../classfile/systemDictionaryShared.cpp | 7 +- src/hotspot/share/classfile/vmClasses.cpp | 7 +- src/hotspot/share/memory/universe.cpp | 7 +- src/hotspot/share/oops/constantPool.cpp | 3 +- src/hotspot/share/oops/klass.cpp | 4 +- src/hotspot/share/prims/whitebox.cpp | 7 +- 18 files changed, 680 insertions(+), 560 deletions(-) create mode 100644 src/hotspot/share/cds/archiveHeapLoader.cpp create mode 100644 src/hotspot/share/cds/archiveHeapLoader.hpp rename src/hotspot/share/cds/{heapShared.inline.hpp => archiveHeapLoader.inline.hpp} (85%) diff --git a/make/hotspot/lib/JvmFeatures.gmk b/make/hotspot/lib/JvmFeatures.gmk index 5daff5e380d98..105ec18eb591a 100644 --- a/make/hotspot/lib/JvmFeatures.gmk +++ b/make/hotspot/lib/JvmFeatures.gmk @@ -120,12 +120,8 @@ endif ifneq ($(call check-jvm-feature, cds), true) JVM_CFLAGS_FEATURES += -DINCLUDE_CDS=0 JVM_EXCLUDE_FILES += \ - cdsProtectionDomain.cpp \ classLoaderDataShared.cpp \ classLoaderExt.cpp \ - dumpTimeSharedClassInfo.cpp \ - lambdaProxyClassDictionary.cpp \ - runTimeSharedClassInfo.cpp \ systemDictionaryShared.cpp JVM_EXCLUDE_PATTERNS += cds/ endif diff --git a/src/hotspot/share/cds/archiveHeapLoader.cpp b/src/hotspot/share/cds/archiveHeapLoader.cpp new file mode 100644 index 0000000000000..393734de7a4f1 --- /dev/null +++ b/src/hotspot/share/cds/archiveHeapLoader.cpp @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2018, 2022, 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. + * + */ + +#include "precompiled.hpp" +#include "cds/archiveHeapLoader.inline.hpp" +#include "cds/filemap.hpp" +#include "cds/heapShared.hpp" +#include "cds/metaspaceShared.hpp" +#include "classfile/classLoaderDataShared.hpp" +#include "classfile/systemDictionaryShared.hpp" +#include "gc/shared/collectedHeap.hpp" +#include "logging/log.hpp" +#include "memory/iterator.inline.hpp" +#include "memory/resourceArea.hpp" +#include "memory/universe.hpp" +#include "utilities/bitMap.inline.hpp" +#include "utilities/copy.hpp" + +#if INCLUDE_CDS_JAVA_HEAP + +bool ArchiveHeapLoader::_closed_regions_mapped = false; +bool ArchiveHeapLoader::_open_regions_mapped = false; +bool ArchiveHeapLoader::_is_loaded = false; +address ArchiveHeapLoader::_narrow_oop_base; +int ArchiveHeapLoader::_narrow_oop_shift; + +// Support for loaded heap. +uintptr_t ArchiveHeapLoader::_loaded_heap_bottom = 0; +uintptr_t ArchiveHeapLoader::_loaded_heap_top = 0; +uintptr_t ArchiveHeapLoader::_dumptime_base_0 = UINTPTR_MAX; +uintptr_t ArchiveHeapLoader::_dumptime_base_1 = UINTPTR_MAX; +uintptr_t ArchiveHeapLoader::_dumptime_base_2 = UINTPTR_MAX; +uintptr_t ArchiveHeapLoader::_dumptime_base_3 = UINTPTR_MAX; +uintptr_t ArchiveHeapLoader::_dumptime_top = 0; +intx ArchiveHeapLoader::_runtime_offset_0 = 0; +intx ArchiveHeapLoader::_runtime_offset_1 = 0; +intx ArchiveHeapLoader::_runtime_offset_2 = 0; +intx ArchiveHeapLoader::_runtime_offset_3 = 0; +bool ArchiveHeapLoader::_loading_failed = false; + +// Support for mapped heap (!UseCompressedOops only) +ptrdiff_t ArchiveHeapLoader::_runtime_delta = 0; + +void ArchiveHeapLoader::init_narrow_oop_decoding(address base, int shift) { + _narrow_oop_base = base; + _narrow_oop_shift = shift; +} + +void ArchiveHeapLoader::fixup_regions() { + FileMapInfo* mapinfo = FileMapInfo::current_info(); + if (is_mapped()) { + mapinfo->fixup_mapped_heap_regions(); + } else if (_loading_failed) { + fill_failed_loaded_region(); + } + if (is_fully_available()) { + if (!MetaspaceShared::use_full_module_graph()) { + // Need to remove all the archived java.lang.Module objects from HeapShared::roots(). + ClassLoaderDataShared::clear_archived_oops(); + } + } + SystemDictionaryShared::update_archived_mirror_native_pointers(); +} + +// ------------------ Support for Region MAPPING ----------------------------------------- + +// Patch all the embedded oop pointers inside an archived heap region, +// to be consistent with the runtime oop encoding. +class PatchCompressedEmbeddedPointers: public BitMapClosure { + narrowOop* _start; + + public: + PatchCompressedEmbeddedPointers(narrowOop* start) : _start(start) {} + + bool do_bit(size_t offset) { + narrowOop* p = _start + offset; + narrowOop v = *p; + assert(!CompressedOops::is_null(v), "null oops should have been filtered out at dump time"); + oop o = ArchiveHeapLoader::decode_from_archive(v); + RawAccess::oop_store(p, o); + return true; + } +}; + +class PatchUncompressedEmbeddedPointers: public BitMapClosure { + oop* _start; + + public: + PatchUncompressedEmbeddedPointers(oop* start) : _start(start) {} + + bool do_bit(size_t offset) { + oop* p = _start + offset; + intptr_t dumptime_oop = (intptr_t)((void*)*p); + assert(dumptime_oop != 0, "null oops should have been filtered out at dump time"); + intptr_t runtime_oop = dumptime_oop + ArchiveHeapLoader::runtime_delta(); + RawAccess::oop_store(p, cast_to_oop(runtime_oop)); + return true; + } +}; + +// Patch all the non-null pointers that are embedded in the archived heap objects +// in this (mapped) region +void ArchiveHeapLoader::patch_embedded_pointers(MemRegion region, address oopmap, + size_t oopmap_size_in_bits) { + BitMapView bm((BitMap::bm_word_t*)oopmap, oopmap_size_in_bits); + +#ifndef PRODUCT + ResourceMark rm; + ResourceBitMap checkBm = HeapShared::calculate_oopmap(region); + assert(bm.is_same(checkBm), "sanity"); +#endif + + if (UseCompressedOops) { + PatchCompressedEmbeddedPointers patcher((narrowOop*)region.start()); + bm.iterate(&patcher); + } else { + PatchUncompressedEmbeddedPointers patcher((oop*)region.start()); + bm.iterate(&patcher); + } +} + +// ------------------ Support for Region LOADING ----------------------------------------- + +// The CDS archive remembers each heap object by its address at dump time, but +// the heap object may be loaded at a different address at run time. This structure is used +// to translate the dump time addresses for all objects in FileMapInfo::space_at(region_index) +// to their runtime addresses. +struct LoadedArchiveHeapRegion { + int _region_index; // index for FileMapInfo::space_at(index) + size_t _region_size; // number of bytes in this region + uintptr_t _dumptime_base; // The dump-time (decoded) address of the first object in this region + intx _runtime_offset; // If an object's dump time address P is within in this region, its + // runtime address is P + _runtime_offset + + static int comparator(const void* a, const void* b) { + LoadedArchiveHeapRegion* reg_a = (LoadedArchiveHeapRegion*)a; + LoadedArchiveHeapRegion* reg_b = (LoadedArchiveHeapRegion*)b; + if (reg_a->_dumptime_base < reg_b->_dumptime_base) { + return -1; + } else if (reg_a->_dumptime_base == reg_b->_dumptime_base) { + return 0; + } else { + return 1; + } + } + + uintptr_t top() { + return _dumptime_base + _region_size; + } +}; + +void ArchiveHeapLoader::init_loaded_heap_relocation(LoadedArchiveHeapRegion* loaded_regions, + int num_loaded_regions) { + _dumptime_base_0 = loaded_regions[0]._dumptime_base; + _dumptime_base_1 = loaded_regions[1]._dumptime_base; + _dumptime_base_2 = loaded_regions[2]._dumptime_base; + _dumptime_base_3 = loaded_regions[3]._dumptime_base; + _dumptime_top = loaded_regions[num_loaded_regions-1].top(); + + _runtime_offset_0 = loaded_regions[0]._runtime_offset; + _runtime_offset_1 = loaded_regions[1]._runtime_offset; + _runtime_offset_2 = loaded_regions[2]._runtime_offset; + _runtime_offset_3 = loaded_regions[3]._runtime_offset; + + assert(2 <= num_loaded_regions && num_loaded_regions <= 4, "must be"); + if (num_loaded_regions < 4) { + _dumptime_base_3 = UINTPTR_MAX; + } + if (num_loaded_regions < 3) { + _dumptime_base_2 = UINTPTR_MAX; + } +} + +bool ArchiveHeapLoader::can_load() { + return Universe::heap()->can_load_archived_objects(); +} + +template +class PatchLoadedRegionPointers: public BitMapClosure { + narrowOop* _start; + intx _offset_0; + intx _offset_1; + intx _offset_2; + intx _offset_3; + uintptr_t _base_0; + uintptr_t _base_1; + uintptr_t _base_2; + uintptr_t _base_3; + uintptr_t _top; + + static_assert(MetaspaceShared::max_num_heap_regions == 4, "can't handle more than 4 regions"); + static_assert(NUM_LOADED_REGIONS >= 2, "we have at least 2 loaded regions"); + static_assert(NUM_LOADED_REGIONS <= 4, "we have at most 4 loaded regions"); + + public: + PatchLoadedRegionPointers(narrowOop* start, LoadedArchiveHeapRegion* loaded_regions) + : _start(start), + _offset_0(loaded_regions[0]._runtime_offset), + _offset_1(loaded_regions[1]._runtime_offset), + _offset_2(loaded_regions[2]._runtime_offset), + _offset_3(loaded_regions[3]._runtime_offset), + _base_0(loaded_regions[0]._dumptime_base), + _base_1(loaded_regions[1]._dumptime_base), + _base_2(loaded_regions[2]._dumptime_base), + _base_3(loaded_regions[3]._dumptime_base) { + _top = loaded_regions[NUM_LOADED_REGIONS-1].top(); + } + + bool do_bit(size_t offset) { + narrowOop* p = _start + offset; + narrowOop v = *p; + assert(!CompressedOops::is_null(v), "null oops should have been filtered out at dump time"); + uintptr_t o = cast_from_oop(ArchiveHeapLoader::decode_from_archive(v)); + assert(_base_0 <= o && o < _top, "must be"); + + + // We usually have only 2 regions for the default archive. Use template to avoid unnecessary comparisons. + if (NUM_LOADED_REGIONS > 3 && o >= _base_3) { + o += _offset_3; + } else if (NUM_LOADED_REGIONS > 2 && o >= _base_2) { + o += _offset_2; + } else if (o >= _base_1) { + o += _offset_1; + } else { + o += _offset_0; + } + ArchiveHeapLoader::assert_in_loaded_heap(o); + RawAccess::oop_store(p, cast_to_oop(o)); + return true; + } +}; + +int ArchiveHeapLoader::init_loaded_regions(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_regions, + MemRegion& archive_space) { + size_t total_bytes = 0; + int num_loaded_regions = 0; + for (int i = MetaspaceShared::first_archive_heap_region; + i <= MetaspaceShared::last_archive_heap_region; i++) { + FileMapRegion* r = mapinfo->space_at(i); + r->assert_is_heap_region(); + if (r->used() > 0) { + assert(is_aligned(r->used(), HeapWordSize), "must be"); + total_bytes += r->used(); + LoadedArchiveHeapRegion* ri = &loaded_regions[num_loaded_regions++]; + ri->_region_index = i; + ri->_region_size = r->used(); + ri->_dumptime_base = (uintptr_t)mapinfo->start_address_as_decoded_from_archive(r); + } + } + + assert(is_aligned(total_bytes, HeapWordSize), "must be"); + size_t word_size = total_bytes / HeapWordSize; + HeapWord* buffer = Universe::heap()->allocate_loaded_archive_space(word_size); + if (buffer == nullptr) { + return 0; + } + + archive_space = MemRegion(buffer, word_size); + _loaded_heap_bottom = (uintptr_t)archive_space.start(); + _loaded_heap_top = _loaded_heap_bottom + total_bytes; + + return num_loaded_regions; +} + +void ArchiveHeapLoader::sort_loaded_regions(LoadedArchiveHeapRegion* loaded_regions, int num_loaded_regions, + uintptr_t buffer) { + // Find the relocation offset of the pointers in each region + qsort(loaded_regions, num_loaded_regions, sizeof(LoadedArchiveHeapRegion), + LoadedArchiveHeapRegion::comparator); + + uintptr_t p = buffer; + for (int i = 0; i < num_loaded_regions; i++) { + // This region will be loaded at p, so all objects inside this + // region will be shifted by ri->offset + LoadedArchiveHeapRegion* ri = &loaded_regions[i]; + ri->_runtime_offset = p - ri->_dumptime_base; + p += ri->_region_size; + } + assert(p == _loaded_heap_top, "must be"); +} + +bool ArchiveHeapLoader::load_regions(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_regions, + int num_loaded_regions, uintptr_t buffer) { + uintptr_t bitmap_base = (uintptr_t)mapinfo->map_bitmap_region(); + if (bitmap_base == 0) { + _loading_failed = true; + return false; // OOM or CRC error + } + uintptr_t load_address = buffer; + for (int i = 0; i < num_loaded_regions; i++) { + LoadedArchiveHeapRegion* ri = &loaded_regions[i]; + FileMapRegion* r = mapinfo->space_at(ri->_region_index); + + if (!mapinfo->read_region(ri->_region_index, (char*)load_address, r->used(), /* do_commit = */ false)) { + // There's no easy way to free the buffer, so we will fill it with zero later + // in fill_failed_loaded_region(), and it will eventually be GC'ed. + log_warning(cds)("Loading of heap region %d has failed. Archived objects are disabled", i); + _loading_failed = true; + return false; + } + log_info(cds)("Loaded heap region #%d at base " INTPTR_FORMAT " top " INTPTR_FORMAT + " size " SIZE_FORMAT_W(6) " delta " INTX_FORMAT, + ri->_region_index, load_address, load_address + ri->_region_size, + ri->_region_size, ri->_runtime_offset); + + uintptr_t oopmap = bitmap_base + r->oopmap_offset(); + BitMapView bm((BitMap::bm_word_t*)oopmap, r->oopmap_size_in_bits()); + + if (num_loaded_regions == 4) { + PatchLoadedRegionPointers<4> patcher((narrowOop*)load_address, loaded_regions); + bm.iterate(&patcher); + } else if (num_loaded_regions == 3) { + PatchLoadedRegionPointers<3> patcher((narrowOop*)load_address, loaded_regions); + bm.iterate(&patcher); + } else { + assert(num_loaded_regions == 2, "must be"); + PatchLoadedRegionPointers<2> patcher((narrowOop*)load_address, loaded_regions); + bm.iterate(&patcher); + } + + load_address += r->used(); + } + + return true; +} + +bool ArchiveHeapLoader::load_heap_regions(FileMapInfo* mapinfo) { + init_narrow_oop_decoding(mapinfo->narrow_oop_base(), mapinfo->narrow_oop_shift()); + + LoadedArchiveHeapRegion loaded_regions[MetaspaceShared::max_num_heap_regions]; + memset(loaded_regions, 0, sizeof(loaded_regions)); + + MemRegion archive_space; + int num_loaded_regions = init_loaded_regions(mapinfo, loaded_regions, archive_space); + if (num_loaded_regions <= 0) { + return false; + } + sort_loaded_regions(loaded_regions, num_loaded_regions, (uintptr_t)archive_space.start()); + if (!load_regions(mapinfo, loaded_regions, num_loaded_regions, (uintptr_t)archive_space.start())) { + assert(_loading_failed, "must be"); + return false; + } + + init_loaded_heap_relocation(loaded_regions, num_loaded_regions); + _is_loaded = true; + + return true; +} + +class VerifyLoadedHeapEmbeddedPointers: public BasicOopIterateClosure { + ResourceHashtable* _table; + + public: + VerifyLoadedHeapEmbeddedPointers(ResourceHashtable* table) : _table(table) {} + + virtual void do_oop(narrowOop* p) { + // This should be called before the loaded regions are modified, so all the embedded pointers + // must be NULL, or must point to a valid object in the loaded regions. + narrowOop v = *p; + if (!CompressedOops::is_null(v)) { + oop o = CompressedOops::decode_not_null(v); + uintptr_t u = cast_from_oop(o); + ArchiveHeapLoader::assert_in_loaded_heap(u); + guarantee(_table->contains(u), "must point to beginning of object in loaded archived regions"); + } + } + virtual void do_oop(oop* p) { + ShouldNotReachHere(); + } +}; + +void ArchiveHeapLoader::finish_initialization() { + if (is_loaded()) { + HeapWord* bottom = (HeapWord*)_loaded_heap_bottom; + HeapWord* top = (HeapWord*)_loaded_heap_top; + + MemRegion archive_space = MemRegion(bottom, top); + Universe::heap()->complete_loaded_archive_space(archive_space); + } + + if (VerifyArchivedFields <= 0 || !is_loaded()) { + return; + } + + log_info(cds, heap)("Verify all oops and pointers in loaded heap"); + + ResourceMark rm; + ResourceHashtable table; + VerifyLoadedHeapEmbeddedPointers verifier(&table); + HeapWord* bottom = (HeapWord*)_loaded_heap_bottom; + HeapWord* top = (HeapWord*)_loaded_heap_top; + + for (HeapWord* p = bottom; p < top; ) { + oop o = cast_to_oop(p); + table.put(cast_from_oop(o), true); + p += o->size(); + } + + for (HeapWord* p = bottom; p < top; ) { + oop o = cast_to_oop(p); + o->oop_iterate(&verifier); + p += o->size(); + } +} + +void ArchiveHeapLoader::fill_failed_loaded_region() { + assert(_loading_failed, "must be"); + if (_loaded_heap_bottom != 0) { + assert(_loaded_heap_top != 0, "must be"); + HeapWord* bottom = (HeapWord*)_loaded_heap_bottom; + HeapWord* top = (HeapWord*)_loaded_heap_top; + Universe::heap()->fill_with_objects(bottom, top - bottom); + } +} + +#endif // INCLUDE_CDS_JAVA_HEAP diff --git a/src/hotspot/share/cds/archiveHeapLoader.hpp b/src/hotspot/share/cds/archiveHeapLoader.hpp new file mode 100644 index 0000000000000..890ec1c57c10a --- /dev/null +++ b/src/hotspot/share/cds/archiveHeapLoader.hpp @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2018, 2022, 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. + * + */ + +#ifndef SHARE_CDS_ARCHIVEHEAPLOADER_HPP +#define SHARE_CDS_ARCHIVEHEAPLOADER_HPP + +#include "gc/shared/gc_globals.hpp" +#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "runtime/globals.hpp" +#include "oops/oopsHierarchy.hpp" +#include "memory/memRegion.hpp" +#include "utilities/macros.hpp" + +class FileMapInfo; +struct LoadedArchiveHeapRegion; + +class ArchiveHeapLoader : AllStatic { +public: + // At runtime, heap regions in the CDS archive can be used in two different ways, + // depending on the GC type: + // - Mapped: (G1 only) the regions are directly mapped into the Java heap + // - Loaded: At VM start-up, the objects in the heap regions are copied into the + // Java heap. This is easier to implement than mapping but + // slightly less efficient, as the embedded pointers need to be relocated. + static bool can_use() { return can_map() || can_load(); } + + // Can this VM map archived heap regions? Currently only G1+compressed{oops,cp} + static bool can_map() { + CDS_JAVA_HEAP_ONLY(return (UseG1GC && UseCompressedClassPointers);) + NOT_CDS_JAVA_HEAP(return false;) + } + static bool is_mapped() { + return closed_regions_mapped() && open_regions_mapped(); + } + + // Can this VM load the objects from archived heap regions into the heap at start-up? + static bool can_load() NOT_CDS_JAVA_HEAP_RETURN_(false); + static void finish_initialization() NOT_CDS_JAVA_HEAP_RETURN; + static bool is_loaded() { + CDS_JAVA_HEAP_ONLY(return _is_loaded;) + NOT_CDS_JAVA_HEAP(return false;) + } + + static bool are_archived_strings_available() { + return is_loaded() || closed_regions_mapped(); + } + static bool are_archived_mirrors_available() { + return is_fully_available(); + } + static bool is_fully_available() { + return is_loaded() || is_mapped(); + } + + static ptrdiff_t runtime_delta() { + assert(!UseCompressedOops, "must be"); + CDS_JAVA_HEAP_ONLY(return _runtime_delta;) + NOT_CDS_JAVA_HEAP_RETURN_(0L); + } + + static void set_closed_regions_mapped() { + CDS_JAVA_HEAP_ONLY(_closed_regions_mapped = true;) + NOT_CDS_JAVA_HEAP_RETURN; + } + static bool closed_regions_mapped() { + CDS_JAVA_HEAP_ONLY(return _closed_regions_mapped;) + NOT_CDS_JAVA_HEAP_RETURN_(false); + } + static void set_open_regions_mapped() { + CDS_JAVA_HEAP_ONLY(_open_regions_mapped = true;) + NOT_CDS_JAVA_HEAP_RETURN; + } + static bool open_regions_mapped() { + CDS_JAVA_HEAP_ONLY(return _open_regions_mapped;) + NOT_CDS_JAVA_HEAP_RETURN_(false); + } + + // NarrowOops stored in the CDS archive may use a different encoding scheme + // than CompressedOops::{base,shift} -- see FileMapInfo::map_heap_regions_impl. + // To decode them, do not use CompressedOops::decode_not_null. Use this + // function instead. + inline static oop decode_from_archive(narrowOop v) NOT_CDS_JAVA_HEAP_RETURN_(NULL); + + static void init_narrow_oop_decoding(address base, int shift) NOT_CDS_JAVA_HEAP_RETURN; + + static void patch_embedded_pointers(MemRegion region, address oopmap, + size_t oopmap_in_bits) NOT_CDS_JAVA_HEAP_RETURN; + + static void fixup_regions() NOT_CDS_JAVA_HEAP_RETURN; + +#if INCLUDE_CDS_JAVA_HEAP +private: + static bool _closed_regions_mapped; + static bool _open_regions_mapped; + static bool _is_loaded; + + // Support for loaded archived heap. These are cached values from + // LoadedArchiveHeapRegion's. + static uintptr_t _dumptime_base_0; + static uintptr_t _dumptime_base_1; + static uintptr_t _dumptime_base_2; + static uintptr_t _dumptime_base_3; + static uintptr_t _dumptime_top; + static intx _runtime_offset_0; + static intx _runtime_offset_1; + static intx _runtime_offset_2; + static intx _runtime_offset_3; + + static uintptr_t _loaded_heap_bottom; + static uintptr_t _loaded_heap_top; + static bool _loading_failed; + + // UseCompressedOops only: Used by decode_from_archive + static address _narrow_oop_base; + static int _narrow_oop_shift; + + // !UseCompressedOops only: used to relocate pointers to the archived objects + static ptrdiff_t _runtime_delta; + + static int init_loaded_regions(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_regions, + MemRegion& archive_space); + static void sort_loaded_regions(LoadedArchiveHeapRegion* loaded_regions, int num_loaded_regions, + uintptr_t buffer); + static bool load_regions(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_regions, + int num_loaded_regions, uintptr_t buffer); + static void init_loaded_heap_relocation(LoadedArchiveHeapRegion* reloc_info, + int num_loaded_regions); + static void fill_failed_loaded_region(); + + static bool is_in_loaded_heap(uintptr_t o) { + return (_loaded_heap_bottom <= o && o < _loaded_heap_top); + } + +public: + + static bool load_heap_regions(FileMapInfo* mapinfo); + static void assert_in_loaded_heap(uintptr_t o) { + assert(is_in_loaded_heap(o), "must be"); + } + + static void set_runtime_delta(ptrdiff_t delta) { + assert(!UseCompressedOops, "must be"); + _runtime_delta = delta; + } +#endif // INCLUDE_CDS_JAVA_HEAP + +}; + +#endif // SHARE_CDS_ARCHIVEHEAPLOADER_HPP diff --git a/src/hotspot/share/cds/heapShared.inline.hpp b/src/hotspot/share/cds/archiveHeapLoader.inline.hpp similarity index 85% rename from src/hotspot/share/cds/heapShared.inline.hpp rename to src/hotspot/share/cds/archiveHeapLoader.inline.hpp index 25f53aa02886d..52346c8c90e68 100644 --- a/src/hotspot/share/cds/heapShared.inline.hpp +++ b/src/hotspot/share/cds/archiveHeapLoader.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ -22,16 +22,17 @@ * */ -#ifndef SHARE_CDS_HEAPSHARED_INLINE_HPP -#define SHARE_CDS_HEAPSHARED_INLINE_HPP +#ifndef SHARE_CDS_ARCHIVEHEAPLOADER_INLINE_HPP +#define SHARE_CDS_ARCHIVEHEAPLOADER_INLINE_HPP + +#include "cds/archiveHeapLoader.hpp" -#include "cds/heapShared.hpp" #include "oops/compressedOops.inline.hpp" #include "utilities/align.hpp" #if INCLUDE_CDS_JAVA_HEAP -inline oop HeapShared::decode_from_archive(narrowOop v) { +inline oop ArchiveHeapLoader::decode_from_archive(narrowOop v) { assert(!CompressedOops::is_null(v), "narrow oop value can never be zero"); uintptr_t p = ((uintptr_t)_narrow_oop_base) + ((uintptr_t)v << _narrow_oop_shift); if (p >= _dumptime_base_0) { @@ -54,4 +55,4 @@ inline oop HeapShared::decode_from_archive(narrowOop v) { #endif -#endif // SHARE_CDS_HEAPSHARED_INLINE_HPP +#endif // SHARE_CDS_ARCHIVEHEAPLOADER_INLINE_HPP diff --git a/src/hotspot/share/cds/archiveUtils.cpp b/src/hotspot/share/cds/archiveUtils.cpp index 971fef4fd4e1e..d1de688529107 100644 --- a/src/hotspot/share/cds/archiveUtils.cpp +++ b/src/hotspot/share/cds/archiveUtils.cpp @@ -24,12 +24,13 @@ #include "precompiled.hpp" #include "cds/archiveBuilder.hpp" +#include "cds/archiveHeapLoader.inline.hpp" #include "cds/archiveUtils.hpp" #include "cds/classListParser.hpp" #include "cds/classListWriter.hpp" #include "cds/dynamicArchive.hpp" #include "cds/filemap.hpp" -#include "cds/heapShared.inline.hpp" +#include "cds/heapShared.hpp" #include "cds/metaspaceShared.hpp" #include "classfile/systemDictionaryShared.hpp" #include "classfile/vmClasses.hpp" @@ -315,19 +316,19 @@ void ReadClosure::do_tag(int tag) { void ReadClosure::do_oop(oop *p) { if (UseCompressedOops) { narrowOop o = CompressedOops::narrow_oop_cast(nextPtr()); - if (CompressedOops::is_null(o) || !HeapShared::is_fully_available()) { + if (CompressedOops::is_null(o) || !ArchiveHeapLoader::is_fully_available()) { *p = NULL; } else { - assert(HeapShared::can_use(), "sanity"); - assert(HeapShared::is_fully_available(), "must be"); - *p = HeapShared::decode_from_archive(o); + assert(ArchiveHeapLoader::can_use(), "sanity"); + assert(ArchiveHeapLoader::is_fully_available(), "must be"); + *p = ArchiveHeapLoader::decode_from_archive(o); } } else { intptr_t dumptime_oop = nextPtr(); - if (dumptime_oop == 0 || !HeapShared::is_fully_available()) { + if (dumptime_oop == 0 || !ArchiveHeapLoader::is_fully_available()) { *p = NULL; } else { - intptr_t runtime_oop = dumptime_oop + HeapShared::runtime_delta(); + intptr_t runtime_oop = dumptime_oop + ArchiveHeapLoader::runtime_delta(); *p = cast_to_oop(runtime_oop); } } diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index a5672f75375e7..f0a5d3c66aeb7 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -25,11 +25,12 @@ #include "precompiled.hpp" #include "jvm.h" #include "cds/archiveBuilder.hpp" +#include "cds/archiveHeapLoader.inline.hpp" #include "cds/archiveUtils.inline.hpp" #include "cds/cds_globals.hpp" #include "cds/dynamicArchive.hpp" #include "cds/filemap.hpp" -#include "cds/heapShared.inline.hpp" +#include "cds/heapShared.hpp" #include "cds/metaspaceShared.hpp" #include "classfile/altHashing.hpp" #include "classfile/classFileStream.hpp" @@ -1970,7 +1971,7 @@ address FileMapInfo::decode_start_address(FileMapRegion* spc, bool with_current_ if (with_current_oop_encoding_mode) { return cast_from_oop
(CompressedOops::decode_raw_not_null(n)); } else { - return cast_from_oop
(HeapShared::decode_from_archive(n)); + return cast_from_oop
(ArchiveHeapLoader::decode_from_archive(n)); } } @@ -2016,10 +2017,10 @@ void FileMapInfo::map_or_load_heap_regions() { bool success = false; if (can_use_heap_regions()) { - if (HeapShared::can_map()) { + if (ArchiveHeapLoader::can_map()) { success = map_heap_regions(); - } else if (HeapShared::can_load()) { - success = HeapShared::load_heap_regions(this); + } else if (ArchiveHeapLoader::can_load()) { + success = ArchiveHeapLoader::load_heap_regions(this); } else { log_info(cds)("Cannot use CDS heap data. UseEpsilonGC, UseG1GC, UseSerialGC or UseParallelGC are required."); } @@ -2085,15 +2086,15 @@ address FileMapInfo::heap_region_runtime_start_address(FileMapRegion* spc) { return start_address_as_decoded_from_archive(spc); } else { assert(is_aligned(spc->mapping_offset(), sizeof(HeapWord)), "must be"); - return header()->heap_begin() + spc->mapping_offset() + HeapShared::runtime_delta(); + return header()->heap_begin() + spc->mapping_offset() + ArchiveHeapLoader::runtime_delta(); } } void FileMapInfo::set_shared_heap_runtime_delta(ptrdiff_t delta) { if (UseCompressedOops) { - HeapShared::init_narrow_oop_decoding(narrow_oop_base() + delta, narrow_oop_shift()); + ArchiveHeapLoader::init_narrow_oop_decoding(narrow_oop_base() + delta, narrow_oop_shift()); } else { - HeapShared::set_runtime_delta(delta); + ArchiveHeapLoader::set_runtime_delta(delta); } } @@ -2209,14 +2210,14 @@ void FileMapInfo::map_heap_regions_impl() { MetaspaceShared::max_num_closed_heap_regions, /*is_open_archive=*/ false, &closed_heap_regions, &num_closed_heap_regions)) { - HeapShared::set_closed_regions_mapped(); + ArchiveHeapLoader::set_closed_regions_mapped(); // Now, map the open heap regions: GC can write into these regions. if (map_heap_regions(MetaspaceShared::first_open_heap_region, MetaspaceShared::max_num_open_heap_regions, /*is_open_archive=*/ true, &open_heap_regions, &num_open_heap_regions)) { - HeapShared::set_open_regions_mapped(); + ArchiveHeapLoader::set_open_regions_mapped(); } } } @@ -2224,12 +2225,12 @@ void FileMapInfo::map_heap_regions_impl() { bool FileMapInfo::map_heap_regions() { map_heap_regions_impl(); - if (!HeapShared::closed_regions_mapped()) { + if (!ArchiveHeapLoader::closed_regions_mapped()) { assert(closed_heap_regions == NULL && num_closed_heap_regions == 0, "sanity"); } - if (!HeapShared::open_regions_mapped()) { + if (!ArchiveHeapLoader::open_regions_mapped()) { assert(open_heap_regions == NULL && num_open_heap_regions == 0, "sanity"); return false; } else { @@ -2336,7 +2337,7 @@ void FileMapInfo::patch_heap_embedded_pointers(MemRegion* regions, int num_regio assert(bitmap_base != NULL, "must have already been mapped"); for (int i=0; imapped_base()) + si->oopmap_offset(), si->oopmap_size_in_bits()); diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index 9899523264b80..59f2cb5ce04d8 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -24,10 +24,10 @@ #include "precompiled.hpp" #include "cds/archiveBuilder.hpp" +#include "cds/archiveHeapLoader.hpp" #include "cds/archiveUtils.hpp" #include "cds/cdsHeapVerifier.hpp" -#include "cds/filemap.hpp" -#include "cds/heapShared.inline.hpp" +#include "cds/heapShared.hpp" #include "cds/metaspaceShared.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderDataShared.hpp" @@ -45,8 +45,6 @@ #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/iterator.inline.hpp" -#include "memory/metadataFactory.hpp" -#include "memory/metaspaceClosure.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/compressedOops.inline.hpp" @@ -56,9 +54,7 @@ #include "oops/typeArrayOop.inline.hpp" #include "prims/jvmtiExport.hpp" #include "runtime/fieldDescriptor.inline.hpp" -#include "runtime/globals_extension.hpp" #include "runtime/init.hpp" -#include "runtime/java.hpp" #include "runtime/javaCalls.hpp" #include "runtime/safepointVerifiers.hpp" #include "utilities/bitMap.inline.hpp" @@ -69,31 +65,9 @@ #if INCLUDE_CDS_JAVA_HEAP -bool HeapShared::_closed_regions_mapped = false; -bool HeapShared::_open_regions_mapped = false; -bool HeapShared::_is_loaded = false; bool HeapShared::_disable_writing = false; -address HeapShared::_narrow_oop_base; -int HeapShared::_narrow_oop_shift; DumpedInternedStrings *HeapShared::_dumped_interned_strings = NULL; -// Support for loaded heap. -uintptr_t HeapShared::_loaded_heap_bottom = 0; -uintptr_t HeapShared::_loaded_heap_top = 0; -uintptr_t HeapShared::_dumptime_base_0 = UINTPTR_MAX; -uintptr_t HeapShared::_dumptime_base_1 = UINTPTR_MAX; -uintptr_t HeapShared::_dumptime_base_2 = UINTPTR_MAX; -uintptr_t HeapShared::_dumptime_base_3 = UINTPTR_MAX; -uintptr_t HeapShared::_dumptime_top = 0; -intx HeapShared::_runtime_offset_0 = 0; -intx HeapShared::_runtime_offset_1 = 0; -intx HeapShared::_runtime_offset_2 = 0; -intx HeapShared::_runtime_offset_3 = 0; -bool HeapShared::_loading_failed = false; - -// Support for mapped heap (!UseCompressedOops only) -ptrdiff_t HeapShared::_runtime_delta = 0; - // // If you add new entries to the following tables, you should know what you're doing! // @@ -162,22 +136,6 @@ bool HeapShared::is_subgraph_root_class(InstanceKlass* ik) { num_fmg_open_archive_subgraph_entry_fields, ik); } -void HeapShared::fixup_regions() { - FileMapInfo* mapinfo = FileMapInfo::current_info(); - if (is_mapped()) { - mapinfo->fixup_mapped_heap_regions(); - } else if (_loading_failed) { - fill_failed_loaded_region(); - } - if (is_fully_available()) { - if (!MetaspaceShared::use_full_module_graph()) { - // Need to remove all the archived java.lang.Module objects from HeapShared::roots(). - ClassLoaderDataShared::clear_archived_oops(); - } - } - SystemDictionaryShared::update_archived_mirror_native_pointers(); -} - unsigned HeapShared::oop_hash(oop const& p) { // Do not call p->identity_hash() as that will update the // object header. @@ -293,7 +251,7 @@ oop HeapShared::get_root(int index, bool clear) { void HeapShared::clear_root(int index) { assert(index >= 0, "sanity"); assert(UseSharedSpaces, "must be"); - if (is_fully_available()) { + if (ArchiveHeapLoader::is_fully_available()) { if (log_is_enabled(Debug, cds, heap)) { oop old = roots()->obj_at(index); log_debug(cds, heap)("Clearing root %d: was " PTR_FORMAT, index, p2i(old)); @@ -438,7 +396,7 @@ void HeapShared::check_enum_obj(int level, // See comments in HeapShared::check_enum_obj() bool HeapShared::initialize_enum_klass(InstanceKlass* k, TRAPS) { - if (!is_fully_available()) { + if (!ArchiveHeapLoader::is_fully_available()) { return false; } @@ -585,11 +543,6 @@ void HeapShared::copy_roots() { log_info(cds)("archived obj roots[%d] = " SIZE_FORMAT " words, klass = %p, obj = %p", length, size, k, mem); } -void HeapShared::init_narrow_oop_decoding(address base, int shift) { - _narrow_oop_base = base; - _narrow_oop_shift = shift; -} - // // Subgraph archiving support // @@ -810,7 +763,7 @@ void HeapShared::serialize(SerializeClosure* soc) { assert(oopDesc::is_oop_or_null(roots_oop), "is oop"); // Create an OopHandle only if we have actually mapped or loaded the roots if (roots_oop != NULL) { - assert(HeapShared::is_fully_available(), "must be"); + assert(ArchiveHeapLoader::is_fully_available(), "must be"); _roots = OopHandle(Universe::vm_global(), roots_oop); } } else { @@ -856,7 +809,7 @@ static void verify_the_heap(Klass* k, const char* which) { // ClassFileLoadHook is enabled, it's possible for this class to be dynamically replaced. In // this case, we will not load the ArchivedKlassSubGraphInfoRecord and will clear its roots. void HeapShared::resolve_classes(JavaThread* THREAD) { - if (!is_fully_available()) { + if (!ArchiveHeapLoader::is_fully_available()) { return; // nothing to do } resolve_classes_for_subgraphs(closed_archive_subgraph_entry_fields, @@ -894,7 +847,7 @@ void HeapShared::resolve_classes_for_subgraph_of(Klass* k, JavaThread* THREAD) { } void HeapShared::initialize_from_archived_subgraph(Klass* k, JavaThread* THREAD) { - if (!is_fully_available()) { + if (!ArchiveHeapLoader::is_fully_available()) { return; // nothing to do } @@ -1663,351 +1616,4 @@ ResourceBitMap HeapShared::calculate_oopmap(MemRegion region) { return oopmap; } -// Patch all the embedded oop pointers inside an archived heap region, -// to be consistent with the runtime oop encoding. -class PatchCompressedEmbeddedPointers: public BitMapClosure { - narrowOop* _start; - - public: - PatchCompressedEmbeddedPointers(narrowOop* start) : _start(start) {} - - bool do_bit(size_t offset) { - narrowOop* p = _start + offset; - narrowOop v = *p; - assert(!CompressedOops::is_null(v), "null oops should have been filtered out at dump time"); - oop o = HeapShared::decode_from_archive(v); - RawAccess::oop_store(p, o); - return true; - } -}; - -class PatchUncompressedEmbeddedPointers: public BitMapClosure { - oop* _start; - - public: - PatchUncompressedEmbeddedPointers(oop* start) : _start(start) {} - - bool do_bit(size_t offset) { - oop* p = _start + offset; - intptr_t dumptime_oop = (intptr_t)((void*)*p); - assert(dumptime_oop != 0, "null oops should have been filtered out at dump time"); - intptr_t runtime_oop = dumptime_oop + HeapShared::runtime_delta(); - RawAccess::oop_store(p, cast_to_oop(runtime_oop)); - return true; - } -}; - -// Patch all the non-null pointers that are embedded in the archived heap objects -// in this region -void HeapShared::patch_embedded_pointers(MemRegion region, address oopmap, - size_t oopmap_size_in_bits) { - BitMapView bm((BitMap::bm_word_t*)oopmap, oopmap_size_in_bits); - -#ifndef PRODUCT - ResourceMark rm; - ResourceBitMap checkBm = calculate_oopmap(region); - assert(bm.is_same(checkBm), "sanity"); -#endif - - if (UseCompressedOops) { - PatchCompressedEmbeddedPointers patcher((narrowOop*)region.start()); - bm.iterate(&patcher); - } else { - PatchUncompressedEmbeddedPointers patcher((oop*)region.start()); - bm.iterate(&patcher); - } -} - -// The CDS archive remembers each heap object by its address at dump time, but -// the heap object may be loaded at a different address at run time. This structure is used -// to translate the dump time addresses for all objects in FileMapInfo::space_at(region_index) -// to their runtime addresses. -struct LoadedArchiveHeapRegion { - int _region_index; // index for FileMapInfo::space_at(index) - size_t _region_size; // number of bytes in this region - uintptr_t _dumptime_base; // The dump-time (decoded) address of the first object in this region - intx _runtime_offset; // If an object's dump time address P is within in this region, its - // runtime address is P + _runtime_offset - - static int comparator(const void* a, const void* b) { - LoadedArchiveHeapRegion* reg_a = (LoadedArchiveHeapRegion*)a; - LoadedArchiveHeapRegion* reg_b = (LoadedArchiveHeapRegion*)b; - if (reg_a->_dumptime_base < reg_b->_dumptime_base) { - return -1; - } else if (reg_a->_dumptime_base == reg_b->_dumptime_base) { - return 0; - } else { - return 1; - } - } - - uintptr_t top() { - return _dumptime_base + _region_size; - } -}; - -void HeapShared::init_loaded_heap_relocation(LoadedArchiveHeapRegion* loaded_regions, - int num_loaded_regions) { - _dumptime_base_0 = loaded_regions[0]._dumptime_base; - _dumptime_base_1 = loaded_regions[1]._dumptime_base; - _dumptime_base_2 = loaded_regions[2]._dumptime_base; - _dumptime_base_3 = loaded_regions[3]._dumptime_base; - _dumptime_top = loaded_regions[num_loaded_regions-1].top(); - - _runtime_offset_0 = loaded_regions[0]._runtime_offset; - _runtime_offset_1 = loaded_regions[1]._runtime_offset; - _runtime_offset_2 = loaded_regions[2]._runtime_offset; - _runtime_offset_3 = loaded_regions[3]._runtime_offset; - - assert(2 <= num_loaded_regions && num_loaded_regions <= 4, "must be"); - if (num_loaded_regions < 4) { - _dumptime_base_3 = UINTPTR_MAX; - } - if (num_loaded_regions < 3) { - _dumptime_base_2 = UINTPTR_MAX; - } -} - -bool HeapShared::can_load() { - return Universe::heap()->can_load_archived_objects(); -} - -template -class PatchLoadedRegionPointers: public BitMapClosure { - narrowOop* _start; - intx _offset_0; - intx _offset_1; - intx _offset_2; - intx _offset_3; - uintptr_t _base_0; - uintptr_t _base_1; - uintptr_t _base_2; - uintptr_t _base_3; - uintptr_t _top; - - static_assert(MetaspaceShared::max_num_heap_regions == 4, "can't handle more than 4 regions"); - static_assert(NUM_LOADED_REGIONS >= 2, "we have at least 2 loaded regions"); - static_assert(NUM_LOADED_REGIONS <= 4, "we have at most 4 loaded regions"); - - public: - PatchLoadedRegionPointers(narrowOop* start, LoadedArchiveHeapRegion* loaded_regions) - : _start(start), - _offset_0(loaded_regions[0]._runtime_offset), - _offset_1(loaded_regions[1]._runtime_offset), - _offset_2(loaded_regions[2]._runtime_offset), - _offset_3(loaded_regions[3]._runtime_offset), - _base_0(loaded_regions[0]._dumptime_base), - _base_1(loaded_regions[1]._dumptime_base), - _base_2(loaded_regions[2]._dumptime_base), - _base_3(loaded_regions[3]._dumptime_base) { - _top = loaded_regions[NUM_LOADED_REGIONS-1].top(); - } - - bool do_bit(size_t offset) { - narrowOop* p = _start + offset; - narrowOop v = *p; - assert(!CompressedOops::is_null(v), "null oops should have been filtered out at dump time"); - uintptr_t o = cast_from_oop(HeapShared::decode_from_archive(v)); - assert(_base_0 <= o && o < _top, "must be"); - - - // We usually have only 2 regions for the default archive. Use template to avoid unnecessary comparisons. - if (NUM_LOADED_REGIONS > 3 && o >= _base_3) { - o += _offset_3; - } else if (NUM_LOADED_REGIONS > 2 && o >= _base_2) { - o += _offset_2; - } else if (o >= _base_1) { - o += _offset_1; - } else { - o += _offset_0; - } - HeapShared::assert_in_loaded_heap(o); - RawAccess::oop_store(p, cast_to_oop(o)); - return true; - } -}; - -int HeapShared::init_loaded_regions(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_regions, - MemRegion& archive_space) { - size_t total_bytes = 0; - int num_loaded_regions = 0; - for (int i = MetaspaceShared::first_archive_heap_region; - i <= MetaspaceShared::last_archive_heap_region; i++) { - FileMapRegion* r = mapinfo->space_at(i); - r->assert_is_heap_region(); - if (r->used() > 0) { - assert(is_aligned(r->used(), HeapWordSize), "must be"); - total_bytes += r->used(); - LoadedArchiveHeapRegion* ri = &loaded_regions[num_loaded_regions++]; - ri->_region_index = i; - ri->_region_size = r->used(); - ri->_dumptime_base = (uintptr_t)mapinfo->start_address_as_decoded_from_archive(r); - } - } - - assert(is_aligned(total_bytes, HeapWordSize), "must be"); - size_t word_size = total_bytes / HeapWordSize; - HeapWord* buffer = Universe::heap()->allocate_loaded_archive_space(word_size); - if (buffer == nullptr) { - return 0; - } - - archive_space = MemRegion(buffer, word_size); - _loaded_heap_bottom = (uintptr_t)archive_space.start(); - _loaded_heap_top = _loaded_heap_bottom + total_bytes; - - return num_loaded_regions; -} - -void HeapShared::sort_loaded_regions(LoadedArchiveHeapRegion* loaded_regions, int num_loaded_regions, - uintptr_t buffer) { - // Find the relocation offset of the pointers in each region - qsort(loaded_regions, num_loaded_regions, sizeof(LoadedArchiveHeapRegion), - LoadedArchiveHeapRegion::comparator); - - uintptr_t p = buffer; - for (int i = 0; i < num_loaded_regions; i++) { - // This region will be loaded at p, so all objects inside this - // region will be shifted by ri->offset - LoadedArchiveHeapRegion* ri = &loaded_regions[i]; - ri->_runtime_offset = p - ri->_dumptime_base; - p += ri->_region_size; - } - assert(p == _loaded_heap_top, "must be"); -} - -bool HeapShared::load_regions(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_regions, - int num_loaded_regions, uintptr_t buffer) { - uintptr_t bitmap_base = (uintptr_t)mapinfo->map_bitmap_region(); - if (bitmap_base == 0) { - _loading_failed = true; - return false; // OOM or CRC error - } - uintptr_t load_address = buffer; - for (int i = 0; i < num_loaded_regions; i++) { - LoadedArchiveHeapRegion* ri = &loaded_regions[i]; - FileMapRegion* r = mapinfo->space_at(ri->_region_index); - - if (!mapinfo->read_region(ri->_region_index, (char*)load_address, r->used(), /* do_commit = */ false)) { - // There's no easy way to free the buffer, so we will fill it with zero later - // in fill_failed_loaded_region(), and it will eventually be GC'ed. - log_warning(cds)("Loading of heap region %d has failed. Archived objects are disabled", i); - _loading_failed = true; - return false; - } - log_info(cds)("Loaded heap region #%d at base " INTPTR_FORMAT " top " INTPTR_FORMAT - " size " SIZE_FORMAT_W(6) " delta " INTX_FORMAT, - ri->_region_index, load_address, load_address + ri->_region_size, - ri->_region_size, ri->_runtime_offset); - - uintptr_t oopmap = bitmap_base + r->oopmap_offset(); - BitMapView bm((BitMap::bm_word_t*)oopmap, r->oopmap_size_in_bits()); - - if (num_loaded_regions == 4) { - PatchLoadedRegionPointers<4> patcher((narrowOop*)load_address, loaded_regions); - bm.iterate(&patcher); - } else if (num_loaded_regions == 3) { - PatchLoadedRegionPointers<3> patcher((narrowOop*)load_address, loaded_regions); - bm.iterate(&patcher); - } else { - assert(num_loaded_regions == 2, "must be"); - PatchLoadedRegionPointers<2> patcher((narrowOop*)load_address, loaded_regions); - bm.iterate(&patcher); - } - - load_address += r->used(); - } - - return true; -} - -bool HeapShared::load_heap_regions(FileMapInfo* mapinfo) { - init_narrow_oop_decoding(mapinfo->narrow_oop_base(), mapinfo->narrow_oop_shift()); - - LoadedArchiveHeapRegion loaded_regions[MetaspaceShared::max_num_heap_regions]; - memset(loaded_regions, 0, sizeof(loaded_regions)); - - MemRegion archive_space; - int num_loaded_regions = init_loaded_regions(mapinfo, loaded_regions, archive_space); - if (num_loaded_regions <= 0) { - return false; - } - sort_loaded_regions(loaded_regions, num_loaded_regions, (uintptr_t)archive_space.start()); - if (!load_regions(mapinfo, loaded_regions, num_loaded_regions, (uintptr_t)archive_space.start())) { - assert(_loading_failed, "must be"); - return false; - } - - init_loaded_heap_relocation(loaded_regions, num_loaded_regions); - _is_loaded = true; - - return true; -} - -class VerifyLoadedHeapEmbeddedPointers: public BasicOopIterateClosure { - ResourceHashtable* _table; - - public: - VerifyLoadedHeapEmbeddedPointers(ResourceHashtable* table) : _table(table) {} - - virtual void do_oop(narrowOop* p) { - // This should be called before the loaded regions are modified, so all the embedded pointers - // must be NULL, or must point to a valid object in the loaded regions. - narrowOop v = *p; - if (!CompressedOops::is_null(v)) { - oop o = CompressedOops::decode_not_null(v); - uintptr_t u = cast_from_oop(o); - HeapShared::assert_in_loaded_heap(u); - guarantee(_table->contains(u), "must point to beginning of object in loaded archived regions"); - } - } - virtual void do_oop(oop* p) { - ShouldNotReachHere(); - } -}; - -void HeapShared::finish_initialization() { - if (is_loaded()) { - HeapWord* bottom = (HeapWord*)_loaded_heap_bottom; - HeapWord* top = (HeapWord*)_loaded_heap_top; - - MemRegion archive_space = MemRegion(bottom, top); - Universe::heap()->complete_loaded_archive_space(archive_space); - } - - if (VerifyArchivedFields <= 0 || !is_loaded()) { - return; - } - - log_info(cds, heap)("Verify all oops and pointers in loaded heap"); - - ResourceMark rm; - ResourceHashtable table; - VerifyLoadedHeapEmbeddedPointers verifier(&table); - HeapWord* bottom = (HeapWord*)_loaded_heap_bottom; - HeapWord* top = (HeapWord*)_loaded_heap_top; - - for (HeapWord* p = bottom; p < top; ) { - oop o = cast_to_oop(p); - table.put(cast_from_oop(o), true); - p += o->size(); - } - - for (HeapWord* p = bottom; p < top; ) { - oop o = cast_to_oop(p); - o->oop_iterate(&verifier); - p += o->size(); - } -} - -void HeapShared::fill_failed_loaded_region() { - assert(_loading_failed, "must be"); - if (_loaded_heap_bottom != 0) { - assert(_loaded_heap_top != 0, "must be"); - HeapWord* bottom = (HeapWord*)_loaded_heap_bottom; - HeapWord* top = (HeapWord*)_loaded_heap_top; - Universe::heap()->fill_with_objects(bottom, top - bottom); - } -} - #endif // INCLUDE_CDS_JAVA_HEAP diff --git a/src/hotspot/share/cds/heapShared.hpp b/src/hotspot/share/cds/heapShared.hpp index 26da658b5699c..662f251d4875a 100644 --- a/src/hotspot/share/cds/heapShared.hpp +++ b/src/hotspot/share/cds/heapShared.hpp @@ -29,16 +29,13 @@ #include "cds/metaspaceShared.hpp" #include "classfile/compactHashtable.hpp" #include "classfile/javaClasses.hpp" -#include "classfile/systemDictionary.hpp" #include "gc/shared/gc_globals.hpp" #include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/compressedOops.hpp" -#include "oops/objArrayKlass.hpp" #include "oops/oop.hpp" #include "oops/oopHandle.hpp" #include "oops/oopsHierarchy.hpp" -#include "oops/typeArrayKlass.hpp" -#include "utilities/bitMap.hpp" #include "utilities/growableArray.hpp" #include "utilities/resourceHash.hpp" @@ -46,6 +43,7 @@ class DumpedInternedStrings; class FileMapInfo; class KlassSubGraphInfo; +class ResourceBitMap; struct ArchivableStaticFieldInfo { const char* klass_name; @@ -148,14 +146,6 @@ class HeapShared: AllStatic { friend class VerifySharedOopClosure; public: - // At runtime, heap regions in the CDS archive can be used in two different ways, - // depending on the GC type: - // - Mapped: (G1 only) the regions are directly mapped into the Java heap - // - Loaded: At VM start-up, the objects in the heap regions are copied into the - // Java heap. This is easier to implement than mapping but - // slightly less efficient, as the embedded pointers need to be relocated. - static bool can_use() { return can_map() || can_load(); } - // Can this VM write heap regions into the CDS archive? Currently only G1+compressed{oops,cp} static bool can_write() { CDS_JAVA_HEAP_ONLY( @@ -170,67 +160,19 @@ class HeapShared: AllStatic { static void disable_writing() { CDS_JAVA_HEAP_ONLY(_disable_writing = true;) } - // Can this VM map archived heap regions? Currently only G1+compressed{oops,cp} - static bool can_map() { - CDS_JAVA_HEAP_ONLY(return (UseG1GC && UseCompressedClassPointers);) - NOT_CDS_JAVA_HEAP(return false;) - } - static bool is_mapped() { - return closed_regions_mapped() && open_regions_mapped(); - } - // Can this VM load the objects from archived heap regions into the heap at start-up? - static bool can_load() NOT_CDS_JAVA_HEAP_RETURN_(false); - static void finish_initialization() NOT_CDS_JAVA_HEAP_RETURN; - static bool is_loaded() { - CDS_JAVA_HEAP_ONLY(return _is_loaded;) - NOT_CDS_JAVA_HEAP(return false;) - } - - static bool are_archived_strings_available() { - return is_loaded() || closed_regions_mapped(); - } - static bool are_archived_mirrors_available() { - return is_fully_available(); - } - static bool is_fully_available() { - return is_loaded() || is_mapped(); - } static bool is_subgraph_root_class(InstanceKlass* ik); private: #if INCLUDE_CDS_JAVA_HEAP static bool _disable_writing; - static bool _closed_regions_mapped; - static bool _open_regions_mapped; - static bool _is_loaded; static DumpedInternedStrings *_dumped_interned_strings; - // Support for loaded archived heap. These are cached values from - // LoadedArchiveHeapRegion's. - static uintptr_t _dumptime_base_0; - static uintptr_t _dumptime_base_1; - static uintptr_t _dumptime_base_2; - static uintptr_t _dumptime_base_3; - static uintptr_t _dumptime_top; - static intx _runtime_offset_0; - static intx _runtime_offset_1; - static intx _runtime_offset_2; - static intx _runtime_offset_3; - static uintptr_t _loaded_heap_bottom; - static uintptr_t _loaded_heap_top; - static bool _loading_failed; - public: static unsigned oop_hash(oop const& p); static unsigned string_oop_hash(oop const& string) { return java_lang_String::hash_code(string); } - static bool load_heap_regions(FileMapInfo* mapinfo); - static void assert_in_loaded_heap(uintptr_t o) { - assert(is_in_loaded_heap(o), "must be"); - } - struct CachedOopInfo { KlassSubGraphInfo* _subgraph_info; oop _referrer; @@ -243,9 +185,6 @@ class HeapShared: AllStatic { KlassSubGraphInfo* subgraph_info, oop orig_obj, bool is_closed_archive); - static bool is_in_loaded_heap(uintptr_t o) { - return (_loaded_heap_bottom <= o && o < _loaded_heap_top); - } typedef ResourceHashtablepatch_heap_embedded_pointers(); - HeapShared::finish_initialization(); + ArchiveHeapLoader::finish_initialization(); // Close the mapinfo file static_mapinfo->close(); @@ -1557,7 +1558,7 @@ bool MetaspaceShared::use_full_module_graph() { if (DumpSharedSpaces) { result &= HeapShared::can_write(); } else if (UseSharedSpaces) { - result &= HeapShared::can_use(); + result &= ArchiveHeapLoader::can_use(); } else { result = false; } diff --git a/src/hotspot/share/classfile/compactHashtable.cpp b/src/hotspot/share/classfile/compactHashtable.cpp index a2bd5f77deb4d..1815c52b37e7a 100644 --- a/src/hotspot/share/classfile/compactHashtable.cpp +++ b/src/hotspot/share/classfile/compactHashtable.cpp @@ -26,7 +26,6 @@ #include "jvm.h" #include "cds/archiveBuilder.hpp" #include "cds/cds_globals.hpp" -#include "cds/heapShared.inline.hpp" #include "classfile/compactHashtable.hpp" #include "classfile/javaClasses.hpp" #include "logging/logMessage.hpp" diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 79ac156bf9d2b..481f6aa77a108 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -25,7 +25,8 @@ #include "precompiled.hpp" #include "jvm.h" #include "cds/archiveBuilder.hpp" -#include "cds/heapShared.inline.hpp" +#include "cds/archiveHeapLoader.hpp" +#include "cds/heapShared.hpp" #include "cds/metaspaceShared.hpp" #include "classfile/altHashing.hpp" #include "classfile/classLoaderData.inline.hpp" @@ -55,6 +56,7 @@ #include "oops/klass.hpp" #include "oops/klass.inline.hpp" #include "oops/method.inline.hpp" +#include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oopCast.inline.hpp" #include "oops/oop.inline.hpp" @@ -894,7 +896,7 @@ void java_lang_Class::fixup_mirror(Klass* k, TRAPS) { } if (k->is_shared() && k->has_archived_mirror_index()) { - if (HeapShared::are_archived_mirrors_available()) { + if (ArchiveHeapLoader::are_archived_mirrors_available()) { bool present = restore_archived_mirror(k, Handle(), Handle(), Handle(), CHECK); assert(present, "Missing archived mirror for %s", k->external_name()); return; @@ -1321,7 +1323,7 @@ bool java_lang_Class::restore_archived_mirror(Klass *k, // mirror is archived, restore log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m)); - if (HeapShared::is_mapped()) { + if (ArchiveHeapLoader::is_mapped()) { assert(Universe::heap()->is_archived_object(m), "must be archived mirror object"); } assert(as_Klass(m) == k, "must be"); diff --git a/src/hotspot/share/classfile/stringTable.cpp b/src/hotspot/share/classfile/stringTable.cpp index d7a7dad0a5026..b9c59e38ba1be 100644 --- a/src/hotspot/share/classfile/stringTable.cpp +++ b/src/hotspot/share/classfile/stringTable.cpp @@ -24,8 +24,9 @@ #include "precompiled.hpp" #include "cds/archiveBuilder.hpp" +#include "cds/archiveHeapLoader.inline.hpp" #include "cds/filemap.hpp" -#include "cds/heapShared.inline.hpp" +#include "cds/heapShared.hpp" #include "classfile/altHashing.hpp" #include "classfile/compactHashtable.hpp" #include "classfile/javaClasses.inline.hpp" @@ -74,13 +75,13 @@ inline oop read_string_from_compact_hashtable(address base_address, u4 offset) { if (UseCompressedOops) { assert(sizeof(narrowOop) == sizeof(offset), "must be"); narrowOop v = CompressedOops::narrow_oop_cast(offset); - return HeapShared::decode_from_archive(v); + return ArchiveHeapLoader::decode_from_archive(v); } else { intptr_t dumptime_oop = (uintptr_t)offset; assert(dumptime_oop != 0, "null strings cannot be interned"); intptr_t runtime_oop = dumptime_oop + (intptr_t)FileMapInfo::current_info()->header()->heap_begin() + - (intptr_t)HeapShared::runtime_delta(); + (intptr_t)ArchiveHeapLoader::runtime_delta(); return (oop)cast_to_oop(runtime_oop); } } @@ -831,7 +832,7 @@ void StringTable::serialize_shared_table_header(SerializeClosure* soc) { if (soc->writing()) { // Sanity. Make sure we don't use the shared table at dump time _shared_table.reset(); - } else if (!HeapShared::are_archived_strings_available()) { + } else if (!ArchiveHeapLoader::are_archived_strings_available()) { _shared_table.reset(); } @@ -861,7 +862,7 @@ class SharedStringTransfer { // _shared_table invalid. Therefore, we proactively copy all the shared // strings into the _local_table, which can deal with oop relocation. void StringTable::transfer_shared_strings_to_local_table() { - assert(HeapShared::is_loaded(), "must be"); + assert(ArchiveHeapLoader::is_loaded(), "must be"); EXCEPTION_MARK; // Reset _shared_table so that during the transfer, StringTable::intern() diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp index 086a9969333df..9e80ffe7fa5dd 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -23,13 +23,13 @@ */ #include "precompiled.hpp" -#include "cds/archiveUtils.hpp" #include "cds/archiveBuilder.hpp" +#include "cds/archiveHeapLoader.hpp" +#include "cds/archiveUtils.hpp" #include "cds/classListParser.hpp" #include "cds/classListWriter.hpp" #include "cds/dynamicArchive.hpp" #include "cds/filemap.hpp" -#include "cds/heapShared.hpp" #include "cds/cdsProtectionDomain.hpp" #include "cds/dumpTimeClassInfo.inline.hpp" #include "cds/metaspaceShared.hpp" @@ -60,6 +60,7 @@ #include "memory/universe.hpp" #include "oops/instanceKlass.hpp" #include "oops/klass.inline.hpp" +#include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/oopHandle.inline.hpp" @@ -1599,7 +1600,7 @@ void SystemDictionaryShared::update_archived_mirror_native_pointers_for(LambdaPr } void SystemDictionaryShared::update_archived_mirror_native_pointers() { - if (!HeapShared::are_archived_mirrors_available()) { + if (!ArchiveHeapLoader::are_archived_mirrors_available()) { return; } if (MetaspaceShared::relocation_delta() == 0) { diff --git a/src/hotspot/share/classfile/vmClasses.cpp b/src/hotspot/share/classfile/vmClasses.cpp index bfbb90d57c807..93e8b97208204 100644 --- a/src/hotspot/share/classfile/vmClasses.cpp +++ b/src/hotspot/share/classfile/vmClasses.cpp @@ -23,10 +23,11 @@ */ #include "precompiled.hpp" -#include "cds/heapShared.hpp" +#include "cds/archiveHeapLoader.hpp" #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/dictionary.hpp" +#include "classfile/javaClasses.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmClasses.hpp" #include "classfile/vmSymbols.hpp" @@ -135,13 +136,13 @@ void vmClasses::resolve_all(TRAPS) { // ConstantPool::restore_unshareable_info (restores the archived // resolved_references array object). // - // HeapShared::fixup_regions() fills the empty + // ArchiveHeapLoader::fixup_regions fills the empty // spaces in the archived heap regions and may use // vmClasses::Object_klass(), so we can do this only after // Object_klass is resolved. See the above resolve_through() // call. No mirror objects are accessed/restored in the above call. // Mirrors are restored after java.lang.Class is loaded. - HeapShared::fixup_regions(); + ArchiveHeapLoader::fixup_regions(); // Initialize the constant pool for the Object_class assert(Object_klass()->is_shared(), "must be"); diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp index 8a9395e28ab4e..636ca1826f10c 100644 --- a/src/hotspot/share/memory/universe.cpp +++ b/src/hotspot/share/memory/universe.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "cds/archiveHeapLoader.hpp" #include "cds/dynamicArchive.hpp" #include "cds/heapShared.hpp" #include "cds/metaspaceShared.hpp" @@ -451,9 +452,9 @@ void Universe::genesis(TRAPS) { void Universe::initialize_basic_type_mirrors(TRAPS) { #if INCLUDE_CDS_JAVA_HEAP if (UseSharedSpaces && - HeapShared::are_archived_mirrors_available() && + ArchiveHeapLoader::are_archived_mirrors_available() && _mirrors[T_INT].resolve() != NULL) { - assert(HeapShared::can_use(), "Sanity"); + assert(ArchiveHeapLoader::can_use(), "Sanity"); // check that all mirrors are mapped also for (int i = T_BOOLEAN; i < T_VOID+1; i++) { @@ -806,7 +807,7 @@ jint universe_init() { // currently mapped regions. MetaspaceShared::initialize_shared_spaces(); StringTable::create_table(); - if (HeapShared::is_loaded()) { + if (ArchiveHeapLoader::is_loaded()) { StringTable::transfer_shared_strings_to_local_table(); } } else diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index c8ec68a21ae55..618871c2c95bf 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "jvm.h" +#include "cds/archiveHeapLoader.hpp" #include "cds/heapShared.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/javaClasses.inline.hpp" @@ -346,7 +347,7 @@ void ConstantPool::restore_unshareable_info(TRAPS) { if (vmClasses::Object_klass_loaded()) { ClassLoaderData* loader_data = pool_holder()->class_loader_data(); #if INCLUDE_CDS_JAVA_HEAP - if (HeapShared::is_fully_available() && + if (ArchiveHeapLoader::is_fully_available() && _cache->archived_references() != NULL) { oop archived = _cache->archived_references(); // Create handle for the archived resolved reference array object diff --git a/src/hotspot/share/oops/klass.cpp b/src/hotspot/share/oops/klass.cpp index 56b6650300344..d0b74dd0e1687 100644 --- a/src/hotspot/share/oops/klass.cpp +++ b/src/hotspot/share/oops/klass.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "jvm_io.h" +#include "cds/archiveHeapLoader.hpp" #include "cds/heapShared.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderDataGraph.inline.hpp" @@ -43,6 +44,7 @@ #include "oops/compressedOops.inline.hpp" #include "oops/instanceKlass.hpp" #include "oops/klass.inline.hpp" +#include "oops/objArrayKlass.hpp" #include "oops/oop.inline.hpp" #include "oops/oopHandle.inline.hpp" #include "prims/jvmtiExport.hpp" @@ -605,7 +607,7 @@ void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protec if (this->has_archived_mirror_index()) { ResourceMark rm(THREAD); log_debug(cds, mirror)("%s has raw archived mirror", external_name()); - if (HeapShared::are_archived_mirrors_available()) { + if (ArchiveHeapLoader::are_archived_mirrors_available()) { bool present = java_lang_Class::restore_archived_mirror(this, loader, module_handle, protection_domain, CHECK); diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index 2f6f1bd0374cc..6aaae031fa04d 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -25,9 +25,10 @@ #include "precompiled.hpp" #include #include "cds.h" +#include "cds/archiveHeapLoader.hpp" #include "cds/cdsConstants.hpp" #include "cds/filemap.hpp" -#include "cds/heapShared.inline.hpp" +#include "cds/heapShared.hpp" #include "cds/metaspaceShared.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/javaClasses.inline.hpp" @@ -1992,7 +1993,7 @@ WB_ENTRY(jboolean, WB_IsSharedClass(JNIEnv* env, jobject wb, jclass clazz)) WB_END WB_ENTRY(jboolean, WB_AreSharedStringsMapped(JNIEnv* env)) - return HeapShared::closed_regions_mapped(); + return ArchiveHeapLoader::closed_regions_mapped(); WB_END WB_ENTRY(jobject, WB_GetResolvedReferences(JNIEnv* env, jobject wb, jclass clazz)) @@ -2017,7 +2018,7 @@ WB_ENTRY(void, WB_LinkClass(JNIEnv* env, jobject wb, jclass clazz)) WB_END WB_ENTRY(jboolean, WB_AreOpenArchiveHeapObjectsMapped(JNIEnv* env)) - return HeapShared::open_regions_mapped(); + return ArchiveHeapLoader::open_regions_mapped(); WB_END WB_ENTRY(jboolean, WB_IsCDSIncluded(JNIEnv* env))