< prev index next > src/hotspot/share/cds/filemap.cpp
Print this page
#include "oops/compressedOops.hpp"
#include "oops/compressedOops.inline.hpp"
#include "oops/compressedKlass.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
+ #include "oops/trainingData.hpp"
#include "oops/typeArrayKlass.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/arguments.hpp"
#include "runtime/globals_extension.hpp"
#include "runtime/java.hpp"
_narrow_klass_shift = ArchiveBuilder::precomputed_narrow_klass_shift();
#endif
} else {
_narrow_klass_pointer_bits = _narrow_klass_shift = -1;
}
+ _type_profile_level = TypeProfileLevel;
+ _type_profile_width = TypeProfileWidth;
+ _bci_profile_width = BciProfileWidth;
+ _profile_traps = ProfileTraps;
+ _spec_trap_limit_extra_entries = SpecTrapLimitExtraEntries;
_max_heap_size = MaxHeapSize;
_use_optimized_module_handling = CDSConfig::is_using_optimized_module_handling();
_has_aot_linked_classes = CDSConfig::is_dumping_aot_linked_classes();
_has_full_module_graph = CDSConfig::is_dumping_full_module_graph();
+ _has_archived_packages = CDSConfig::is_dumping_packages();
+ _has_archived_protection_domains = CDSConfig::is_dumping_protection_domains();
+ _gc_kind = (int)Universe::heap()->kind();
+ jio_snprintf(_gc_name, sizeof(_gc_name), Universe::heap()->name());
// The following fields are for sanity checks for whether this archive
// will function correctly with this JVM and the bootclasspath it's
// invoked with.
st->print_cr("- _ro_ptrmap_start_pos: %zu", _ro_ptrmap_start_pos);
st->print_cr("- allow_archiving_with_java_agent:%d", _allow_archiving_with_java_agent);
st->print_cr("- use_optimized_module_handling: %d", _use_optimized_module_handling);
st->print_cr("- has_full_module_graph %d", _has_full_module_graph);
st->print_cr("- has_aot_linked_classes %d", _has_aot_linked_classes);
+ st->print_cr("- has_archived_packages %d", _has_archived_packages);
+ st->print_cr("- has_archived_protection_domains %d", _has_archived_protection_domains);
+ st->print_cr("- ptrmap_size_in_bits: %zu", _ptrmap_size_in_bits);
}
bool FileMapInfo::validate_class_location() {
assert(CDSConfig::is_using_archive(), "runtime only");
log_info(cds)("Shared file region (%s) %d: %8zu"
" bytes, addr " INTPTR_FORMAT " file offset 0x%08" PRIxPTR
" crc 0x%08x",
region_name(region), region, size, p2i(requested_base), _file_offset, crc);
} else {
- log_info(cds)("Shared file region (%s) %d: %8zu"
+ log_info(cds)("Shared file region (%s) %d: %8zu"
" bytes", region_name(region), region, size);
}
r->init(region, mapping_offset, size, read_only, allow_exec, crc);
assert(map->size() <= old_size, "sanity");
return first_set;
}
- char* FileMapInfo::write_bitmap_region(CHeapBitMap* rw_ptrmap, CHeapBitMap* ro_ptrmap, ArchiveHeapInfo* heap_info,
+ char* FileMapInfo::write_bitmap_region(CHeapBitMap* rw_ptrmap, CHeapBitMap* ro_ptrmap,
+ CHeapBitMap* ac_ptrmap,
+ ArchiveHeapInfo* heap_info,
size_t &size_in_bytes) {
size_t removed_rw_leading_zeros = remove_bitmap_zeros(rw_ptrmap);
size_t removed_ro_leading_zeros = remove_bitmap_zeros(ro_ptrmap);
header()->set_rw_ptrmap_start_pos(removed_rw_leading_zeros);
header()->set_ro_ptrmap_start_pos(removed_ro_leading_zeros);
- size_in_bytes = rw_ptrmap->size_in_bytes() + ro_ptrmap->size_in_bytes();
+ size_in_bytes = rw_ptrmap->size_in_bytes() + ro_ptrmap->size_in_bytes() + ac_ptrmap->size_in_bytes();
if (heap_info->is_used()) {
// Remove leading and trailing zeros
size_t removed_oop_leading_zeros = remove_bitmap_zeros(heap_info->oopmap());
size_t removed_ptr_leading_zeros = remove_bitmap_zeros(heap_info->ptrmap());
written = write_bitmap(rw_ptrmap, buffer, written);
region_at(MetaspaceShared::ro)->init_ptrmap(written, ro_ptrmap->size());
written = write_bitmap(ro_ptrmap, buffer, written);
+ region_at(MetaspaceShared::ac)->init_ptrmap(written, ac_ptrmap->size());
+ written = write_bitmap(ac_ptrmap, buffer, written);
+
if (heap_info->is_used()) {
FileMapRegion* r = region_at(MetaspaceShared::hp);
r->init_oopmap(written, heap_info->oopmap()->size());
written = write_bitmap(heap_info->oopmap(), buffer, written);
}
} else {
// Note that this may either be a "fresh" mapping into unreserved address
// space (Windows, first mapping attempt), or a mapping into pre-reserved
// space (Posix). See also comment in MetaspaceShared::map_archives().
+ bool read_only = r->read_only() && !CDSConfig::is_dumping_final_static_archive();
char* base = map_memory(_fd, _full_path, r->file_offset(),
- requested_addr, size, r->read_only(),
+ requested_addr, size, read_only,
r->allow_exec(), mtClassShared);
if (base != requested_addr) {
log_info(cds)("Unable to map %s shared space at " INTPTR_FORMAT,
shared_region_name[i], p2i(requested_addr));
_memory_mapping_failed = true;
return false;
} else {
assert(mapped_base == requested_base, "must be");
r->set_mapped_from_file(true);
r->set_mapped_base(mapped_base);
+ relocate_pointers_in_aot_code_region();
log_info(cds)("Mapped static region #%d at base " INTPTR_FORMAT " top " INTPTR_FORMAT " (%s)",
MetaspaceShared::ac, p2i(r->mapped_base()), p2i(r->mapped_end()),
shared_region_name[MetaspaceShared::ac]);
return true;
}
}
+ class CachedCodeRelocator: public BitMapClosure {
+ address _code_requested_base;
+ address* _patch_base;
+ intx _code_delta;
+ intx _metadata_delta;
+
+ public:
+ CachedCodeRelocator(address code_requested_base, address code_mapped_base,
+ intx metadata_delta) {
+ _code_requested_base = code_requested_base;
+ _patch_base = (address*)code_mapped_base;
+ _code_delta = code_mapped_base - code_requested_base;
+ _metadata_delta = metadata_delta;
+ }
+
+ bool do_bit(size_t offset) {
+ address* p = _patch_base + offset;
+ address requested_ptr = *p;
+ if (requested_ptr < _code_requested_base) {
+ *p = requested_ptr + _metadata_delta;
+ } else {
+ *p = requested_ptr + _code_delta;
+ }
+ return true; // keep iterating
+ }
+ };
+
+ void FileMapInfo::relocate_pointers_in_aot_code_region() {
+ FileMapRegion* r = region_at(MetaspaceShared::ac);
+ char* bitmap_base = map_bitmap_region();
+
+ BitMapView ac_ptrmap = ptrmap_view(MetaspaceShared::ac);
+ if (ac_ptrmap.size() == 0) {
+ return;
+ }
+
+ address core_regions_requested_base = (address)header()->requested_base_address();
+ address core_regions_mapped_base = (address)header()->mapped_base_address();
+ address ac_region_requested_base = core_regions_requested_base + r->mapping_offset();
+ address ac_region_mapped_base = (address)r->mapped_base();
+
+ size_t max_bits_for_core_regions = pointer_delta(mapped_end(), mapped_base(), // FIXME - renamed to core_regions_mapped_base(), etc
+ sizeof(address));
+
+ CachedCodeRelocator patcher(ac_region_requested_base, ac_region_mapped_base,
+ core_regions_mapped_base - core_regions_requested_base);
+ ac_ptrmap.iterate(&patcher);
+ }
+
class SharedDataRelocationTask : public ArchiveWorkerTask {
private:
BitMapView* const _rw_bm;
BitMapView* const _ro_bm;
SharedDataRelocator* const _rw_reloc;
}
}
}
if (!success) {
- if (CDSConfig::is_using_aot_linked_classes()) {
+ if (CDSConfig::is_using_aot_linked_classes() && !CDSConfig::is_dumping_final_static_archive()) {
// It's too late to recover -- we have already committed to use the archived metaspace objects, but
// the archived heap objects cannot be loaded, so we don't have the archived FMG to guarantee that
// all AOT-linked classes are visible.
//
// We get here because the heap is too small. The app will fail anyway. So let's quit.
}
if (JvmtiExport::has_early_vmstart_env()) {
log_error(cds)("CDS archive has aot-linked classes. It cannot be used when JVMTI early vm start is in use.");
return false;
}
- if (!CDSConfig::is_using_full_module_graph()) {
+ if (!CDSConfig::is_using_full_module_graph() && !CDSConfig::is_dumping_final_static_archive()) {
log_error(cds)("CDS archive has aot-linked classes. It cannot be used when archived full module graph is not used.");
return false;
}
const char* prop = Arguments::get_property("java.security.manager");
if (prop != nullptr && strcmp(prop, "disallow") != 0) {
log_error(cds)("CDS archive has aot-linked classes. It cannot be used with -Djava.security.manager=%s.", prop);
return false;
}
+ if (header()->gc_kind() != (int)Universe::heap()->kind()) {
+ log_error(cds)("CDS archive has aot-linked classes. It cannot be used because GC used during dump time (%s) is not the same as runtime (%s)",
+ header()->gc_name(), Universe::heap()->name());
+ return false;
+ }
+
#if INCLUDE_JVMTI
if (Arguments::has_jdwp_agent()) {
log_error(cds)("CDS archive has aot-linked classes. It cannot be used with JDWP agent");
return false;
}
" does not equal the current CompactStrings setting (%s).", file_type,
_compact_strings ? "enabled" : "disabled",
CompactStrings ? "enabled" : "disabled");
return false;
}
+ if (TrainingData::have_data()) {
+ if (_type_profile_level != TypeProfileLevel) {
+ log_info(cds)("The %s's TypeProfileLevel setting (%d)"
+ " does not equal the current TypeProfileLevel setting (%d).", file_type,
+ _type_profile_level, TypeProfileLevel);
+ return false;
+ }
+ if (_type_profile_width != TypeProfileWidth) {
+ log_info(cds)("The %s's TypeProfileWidth setting (%d)"
+ " does not equal the current TypeProfileWidth setting (%d).", file_type,
+ (int)_type_profile_width, (int)TypeProfileWidth);
+ return false;
+
+ }
+ if (_bci_profile_width != BciProfileWidth) {
+ log_info(cds)("The %s's BciProfileWidth setting (%d)"
+ " does not equal the current BciProfileWidth setting (%d).", file_type,
+ (int)_bci_profile_width, (int)BciProfileWidth);
+ return false;
+ }
+ if (_profile_traps != ProfileTraps) {
+ log_info(cds)("The %s's ProfileTraps setting (%s)"
+ " does not equal the current ProfileTraps setting (%s).", file_type,
+ _profile_traps ? "enabled" : "disabled",
+ ProfileTraps ? "enabled" : "disabled");
+
+ return false;
+ }
+ if (_spec_trap_limit_extra_entries != SpecTrapLimitExtraEntries) {
+ log_info(cds)("The %s's SpecTrapLimitExtraEntries setting (%d)"
+ " does not equal the current SpecTrapLimitExtraEntries setting (%d).", file_type,
+ _spec_trap_limit_extra_entries, SpecTrapLimitExtraEntries);
+ return false;
+
+ }
+ }
// This must be done after header validation because it might change the
// header data
const char* prop = Arguments::get_property("java.system.class.loader");
if (prop != nullptr) {
if (is_static()) {
// Only the static archive can contain the full module graph.
if (!_has_full_module_graph) {
CDSConfig::stop_using_full_module_graph("archive was created without full module graph");
}
+
+ if (_has_archived_packages) {
+ CDSConfig::set_is_loading_packages();
+ }
+ if (_has_archived_protection_domains) {
+ CDSConfig::set_is_loading_protection_domains();
+ }
}
return true;
}
< prev index next >