< prev index next >

src/hotspot/share/cds/dumpTimeClassInfo.cpp

Print this page
@@ -22,10 +22,11 @@
   *
   */
  
  #include "precompiled.hpp"
  #include "cds/archiveBuilder.hpp"
+ #include "cds/cdsConfig.hpp"
  #include "cds/dumpTimeClassInfo.inline.hpp"
  #include "cds/runTimeClassInfo.hpp"
  #include "classfile/classLoader.hpp"
  #include "classfile/classLoaderData.inline.hpp"
  #include "classfile/systemDictionaryShared.hpp"

@@ -40,10 +41,34 @@
    if (_loader_constraints != nullptr) {
      delete _loader_constraints;
    }
  }
  
+ bool DumpTimeClassInfo::is_excluded() {
+   if (_excluded) {
+     return true;
+   }
+   if (_failed_verification) {
+     if (CDSConfig::preserve_all_dumptime_verification_states(_klass)) {
+       assert(CDSConfig::is_dumping_aot_linked_classes(), "sanity");
+       // If the verification states are preserved, _klass will be archived in unlinked state. This is
+       // necessary to support the following scenario, where the verification of X requires that
+       // A be a subclass of B:
+       //     class X {
+       //        B getB() { return new A(); }
+       //     }
+       // If X and B can be verified, but A fails verification, we still archive A (in a preloaded
+       // SystemDictionary) so that at runtime we cannot subvert the verification of X by replacing
+       // A with a version that is not a subtype of B.
+     } else {
+       // Don't archive this class. At runtime, load it from classfile and rerun verification.
+       return true;
+     }
+   }
+   return false;
+ }
+ 
  size_t DumpTimeClassInfo::runtime_info_bytesize() const {
    return RunTimeClassInfo::byte_size(_klass, num_verifier_constraints(),
                                       num_loader_constraints(),
                                       num_enum_klass_static_fields());
  }

@@ -141,20 +166,24 @@
  bool DumpTimeClassInfo::is_builtin() {
    return SystemDictionaryShared::is_builtin(_klass);
  }
  
  DumpTimeClassInfo* DumpTimeSharedClassTable::allocate_info(InstanceKlass* k) {
-   assert(!k->is_shared(), "Do not call with shared classes");
+   if (!CDSConfig::is_dumping_final_static_archive()) {
+     assert(!k->is_shared(), "Do not call with shared classes");
+   }
    bool created;
    DumpTimeClassInfo* p = put_if_absent(k, &created);
    assert(created, "must not exist in table");
    p->_klass = k;
    return p;
  }
  
  DumpTimeClassInfo* DumpTimeSharedClassTable::get_info(InstanceKlass* k) {
-   assert(!k->is_shared(), "Do not call with shared classes");
+   if (!CDSConfig::is_dumping_final_static_archive()) {
+     assert(!k->is_shared(), "Do not call with shared classes");
+   }
    DumpTimeClassInfo* p = get(k);
    assert(p != nullptr, "we must not see any non-shared InstanceKlass* that's "
           "not stored with SystemDictionaryShared::init_dumptime_info");
    assert(p->_klass == k, "Sanity");
    return p;
< prev index next >