diff a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -62,10 +62,11 @@ #include "memory/metaspaceClosure.hpp" #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/compressedKlass.inline.hpp" +#include "oops/fieldStreams.inline.hpp" #include "oops/instanceKlass.hpp" #include "oops/klass.inline.hpp" #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" @@ -296,10 +297,22 @@ add_candidate(InstanceKlass::cast(constraint_bottom_class)); } return true; // Keep iterating. }); } + + // Inline fields need to have their layouts preserved between dumptime and runtime. + // To ensure this, the types of the fields must be stored in the archive along with + // the field holder. + if (k->has_inlined_fields() || k->has_null_restricted_static_fields()) { + for (AllFieldStream fs(k); !fs.done(); fs.next()) { + if (fs.is_flat() || fs.is_null_free_inline_type()) { + InlineKlass* field_klass = k->get_inline_type_field_klass(fs.index()); + add_candidate(InstanceKlass::cast(field_klass)); + } + } + } } public: ExclusionCheckCandidates(InstanceKlass* k) { add_candidate(k); @@ -518,10 +531,24 @@ // At least one verification constraint class has been excluded return true; } } + // If any of the null restricted or flat field types are excluded, the current + // klass must be excluded as well, otherwise there is no guarantee that the + // field layouts will be consistent at runtime. + if (k->has_inlined_fields() || k->has_null_restricted_static_fields()) { + for (AllFieldStream fs(k); !fs.done(); fs.next()) { + if (fs.is_flat() || fs.is_null_free_inline_type()) { + InlineKlass* field_klass = k->get_inline_type_field_klass(fs.index()); + if (is_dependency_excluded(k, InstanceKlass::cast(field_klass), "inline field type")) { + return true; + } + } + } + } + return false; } bool SystemDictionaryShared::is_dependency_excluded(InstanceKlass* k, InstanceKlass* dependency, const char* type) { if (CDSConfig::is_dumping_dynamic_archive() && AOTMetaspace::in_aot_cache(dependency)) {