< prev index next > src/hotspot/share/cds/cdsHeapVerifier.cpp
Print this page
#include "logging/logStream.hpp"
#include "memory/resourceArea.hpp"
#include "oops/fieldStreams.inline.hpp"
#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
+ #include "oops/oopHandle.inline.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#if INCLUDE_CDS_JAVA_HEAP
// CDSHeapVerifier is used to check for problems where an archived object references a
// Unfortunately this needs to be manually maintained. If
// test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedEnumTest.java fails,
// you might need to fix the core library code, or fix the ADD_EXCL entries below.
//
// class field type
! ADD_EXCL("java/lang/ClassLoader", "scl"); // A
ADD_EXCL("java/lang/Module", "ALL_UNNAMED_MODULE", // A
"ALL_UNNAMED_MODULE_SET", // A
"EVERYONE_MODULE", // A
"EVERYONE_SET"); // A
// Unfortunately this needs to be manually maintained. If
// test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchivedEnumTest.java fails,
// you might need to fix the core library code, or fix the ADD_EXCL entries below.
//
// class field type
! ADD_EXCL("java/lang/ClassLoader$Holder", "scl"); // A
ADD_EXCL("java/lang/Module", "ALL_UNNAMED_MODULE", // A
"ALL_UNNAMED_MODULE_SET", // A
"EVERYONE_MODULE", // A
"EVERYONE_SET"); // A
"FALSE", // D
"TRUE", // D
"ZERO"); // D
}
+ if (CDSConfig::is_dumping_packages()) {
+ ADD_EXCL("java/lang/Package$VersionInfo", "NULL_VERSION_INFO"); // D
+ }
+
+ if (CDSConfig::is_dumping_dynamic_proxies()) {
+ ADD_EXCL("java/lang/reflect/ProxyGenerator", "CD_Object_array"); // D
+ }
+
+ // These are used by BuiltinClassLoader::negativeLookupCache, etc but seem to be
+ // OK. TODO - we should completely disable the caching unless ArchiveLoaderLookupCache
+ // is enabled
+ ADD_EXCL("java/lang/Boolean", "TRUE", // E
+ "FALSE"); // E
+
# undef ADD_EXCL
ClassLoaderDataGraph::classes_do(this);
}
_table.put(field, info);
}
// This function is called once for every archived heap object. Warn if this object is referenced by
// a static field of a class that's not aot-initialized.
! inline bool CDSHeapVerifier::do_entry(oop& orig_obj, HeapShared::CachedOopInfo& value) {
_archived_objs++;
if (java_lang_String::is_instance(orig_obj) && HeapShared::is_dumped_interned_string(orig_obj)) {
// It's quite often for static fields to have interned strings. These are most likely not
// problematic (and are hard to filter). So we will ignore them.
_table.put(field, info);
}
// This function is called once for every archived heap object. Warn if this object is referenced by
// a static field of a class that's not aot-initialized.
! inline bool CDSHeapVerifier::do_entry(OopHandle& orig_obj_handle, HeapShared::CachedOopInfo& value) {
+ oop orig_obj = orig_obj_handle.resolve();
_archived_objs++;
if (java_lang_String::is_instance(orig_obj) && HeapShared::is_dumped_interned_string(orig_obj)) {
// It's quite often for static fields to have interned strings. These are most likely not
// problematic (and are hard to filter). So we will ignore them.
}
};
// Call this function (from gdb, etc) if you want to know why an object is archived.
void CDSHeapVerifier::trace_to_root(outputStream* st, oop orig_obj) {
! HeapShared::CachedOopInfo* info = HeapShared::archived_object_cache()->get(orig_obj);
if (info != nullptr) {
trace_to_root(st, orig_obj, nullptr, info);
} else {
st->print_cr("Not an archived object??");
}
}
};
// Call this function (from gdb, etc) if you want to know why an object is archived.
void CDSHeapVerifier::trace_to_root(outputStream* st, oop orig_obj) {
! HeapShared::CachedOopInfo* info = HeapShared::get_cached_oop_info(orig_obj);
if (info != nullptr) {
trace_to_root(st, orig_obj, nullptr, info);
} else {
st->print_cr("Not an archived object??");
}
}
int CDSHeapVerifier::trace_to_root(outputStream* st, oop orig_obj, oop orig_field, HeapShared::CachedOopInfo* info) {
int level = 0;
if (info->orig_referrer() != nullptr) {
! HeapShared::CachedOopInfo* ref = HeapShared::archived_object_cache()->get(info->orig_referrer());
assert(ref != nullptr, "sanity");
level = trace_to_root(st, info->orig_referrer(), orig_obj, ref) + 1;
} else if (java_lang_String::is_instance(orig_obj)) {
st->print_cr("[%2d] (shared string table)", level++);
}
}
int CDSHeapVerifier::trace_to_root(outputStream* st, oop orig_obj, oop orig_field, HeapShared::CachedOopInfo* info) {
int level = 0;
if (info->orig_referrer() != nullptr) {
! HeapShared::CachedOopInfo* ref = HeapShared::get_cached_oop_info(info->orig_referrer());
assert(ref != nullptr, "sanity");
level = trace_to_root(st, info->orig_referrer(), orig_obj, ref) + 1;
} else if (java_lang_String::is_instance(orig_obj)) {
st->print_cr("[%2d] (shared string table)", level++);
}
< prev index next >