< prev index next >

src/hotspot/share/classfile/systemDictionaryShared.cpp

Print this page
@@ -32,10 +32,11 @@
  #include "cds/classListWriter.hpp"
  #include "cds/dumpTimeClassInfo.inline.hpp"
  #include "cds/dynamicArchive.hpp"
  #include "cds/filemap.hpp"
  #include "cds/heapShared.hpp"
+ #include "cds/lambdaFormInvokers.inline.hpp"
  #include "cds/lambdaProxyClassDictionary.hpp"
  #include "cds/lambdaFormInvokers.inline.hpp"
  #include "cds/metaspaceShared.hpp"
  #include "cds/runTimeClassInfo.hpp"
  #include "cds/unregisteredClasses.hpp"

@@ -63,10 +64,11 @@
  #include "memory/resourceArea.hpp"
  #include "memory/universe.hpp"
  #include "oops/compressedKlass.inline.hpp"
  #include "oops/instanceKlass.hpp"
  #include "oops/klass.inline.hpp"
+ #include "oops/methodData.hpp"
  #include "oops/objArrayKlass.hpp"
  #include "oops/objArrayOop.inline.hpp"
  #include "oops/oop.inline.hpp"
  #include "oops/oopHandle.inline.hpp"
  #include "oops/typeArrayOop.inline.hpp"

@@ -104,12 +106,15 @@
    if (ik != nullptr && !ik->shared_loading_failed()) {
      if ((SystemDictionary::is_system_class_loader(class_loader()) && ik->is_shared_app_class())  ||
          (SystemDictionary::is_platform_class_loader(class_loader()) && ik->is_shared_platform_class())) {
        SharedClassLoadingMark slm(THREAD, ik);
        PackageEntry* pkg_entry = CDSProtectionDomain::get_package_entry_from_class(ik, class_loader);
-       Handle protection_domain =
-         CDSProtectionDomain::init_security_info(class_loader, ik, pkg_entry, CHECK_NULL);
+       Handle protection_domain;
+       if (!class_name->starts_with("jdk/proxy")) // java/lang/reflect/Proxy$ProxyBuilder defines the proxy classes with a null protection domain.
+       {
+         protection_domain = CDSProtectionDomain::init_security_info(class_loader, ik, pkg_entry, CHECK_NULL);
+       }
        return load_shared_class(ik, class_loader, protection_domain, nullptr, pkg_entry, THREAD);
      }
    }
    return nullptr;
  }

@@ -291,11 +296,13 @@
    if (is_jfr_event_class(k)) {
      // We cannot include JFR event classes because they need runtime-specific
      // instrumentation in order to work with -XX:FlightRecorderOptions:retransform=false.
      // There are only a small number of these classes, so it's not worthwhile to
      // support them and make CDS more complicated.
-     return warn_excluded(k, "JFR event class");
+     if (!CDSConfig::is_dumping_reflection_data()) { // FIXME: !!! HACK !!!
+       return warn_excluded(k, "JFR event class");
+     }
    }
  
    if (!k->is_linked()) {
      if (has_class_failed_verification(k)) {
        return warn_excluded(k, "Failed verification");

@@ -310,11 +317,11 @@
        // When dumping the final static archive, we will unconditionally load and link all
        // classes from tje preimage. We don't want to get a VerifyError when linking this class.
        return warn_excluded(k, "Unlinked class not supported by AOTConfiguration");
      }
    } else {
-     if (!k->can_be_verified_at_dumptime()) {
+     if (!k->can_be_verified_at_dumptime() && !CDSConfig::preserve_all_dumptime_verification_states(k)) {
        // We have an old class that has been linked (e.g., it's been executed during
        // dump time). This class has been verified using the old verifier, which
        // doesn't save the verification constraints, so check_verification_constraints()
        // won't work at runtime.
        // As a result, we cannot store this class. It must be loaded and fully verified

@@ -341,14 +348,21 @@
      }
    }
  
    if (k == UnregisteredClasses::UnregisteredClassLoader_klass()) {
      ResourceMark rm;
-     log_info(cds)("Skipping %s: used only when dumping CDS archive", k->name()->as_C_string());
+     log_debug(cds)("Skipping %s: used only when dumping CDS archive", k->name()->as_C_string());
+     return true;
+   }
+ 
+   if (k->name()->equals("jdk/internal/misc/CDS$DummyForDynamicArchive") && !CDSConfig::is_dumping_dynamic_archive()) {
+     ResourceMark rm;
+     log_debug(cds)("Skipping %s: used only when dumping dynamic CDS archive", k->name()->as_C_string());
      return true;
    }
  
+ 
    return false; // false == k should NOT be excluded
  }
  
  bool SystemDictionaryShared::is_builtin_loader(ClassLoaderData* loader_data) {
    oop class_loader = loader_data->class_loader();

@@ -753,10 +767,21 @@
  }
  
  bool SystemDictionaryShared::add_verification_constraint(InstanceKlass* k, Symbol* name,
           Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object) {
    assert(CDSConfig::is_dumping_archive(), "sanity");
+   if (CDSConfig::is_dumping_dynamic_archive() && k->is_shared()) {
+     // k is a new class in the static archive, but one of its supertypes is an old class, so k wasn't
+     // verified during dump time. No need to record constraints as k won't be included in the dynamic archive.
+     return false;
+   }
+   if (CDSConfig::is_dumping_aot_linked_classes() && is_builtin(k)) {
+     // There's no need to save verification constraints
+     // TODO -- double check the logic before integrating into mainline!!
+     return false;
+   }
+ 
    DumpTimeClassInfo* info = get_info(k);
    info->add_verification_constraint(k, name, from_name, from_field_is_protected,
                                      from_is_array, from_is_object);
  
    if (CDSConfig::is_dumping_dynamic_archive()) {

@@ -972,11 +997,11 @@
      }
    }
  }
  
  unsigned int SystemDictionaryShared::hash_for_shared_dictionary(address ptr) {
-   if (ArchiveBuilder::is_active()) {
+   if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space(ptr)) {
      uintx offset = ArchiveBuilder::current()->any_to_offset(ptr);
      unsigned int hash = primitive_hash<uintx>(offset);
      DEBUG_ONLY({
          if (MetaspaceObj::is_shared((const MetaspaceObj*)ptr)) {
            assert(hash == SystemDictionaryShared::hash_for_shared_dictionary_quick(ptr), "must be");

@@ -1210,5 +1235,59 @@
    if (_dumptime_table->count_of(true) == 0 && _dumptime_table->count_of(false) == 0){
      return true;
    }
    return false;
  }
+ 
+ void SystemDictionaryShared::create_loader_positive_lookup_cache(TRAPS) {
+   GrowableArray<InstanceKlass*> shared_classes_list;
+   {
+     // With static dumping, we have only a single Java thread (see JVM_StartThread) so
+     // no no other threads should be loading classes. Otherwise, the code below may miss some
+     // classes that are loaded concurrently.
+     assert(CDSConfig::is_dumping_static_archive(), "no other threads should be loading classes");
+ 
+     MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag);
+     _dumptime_table->iterate_all_classes_in_builtin_loaders([&](InstanceKlass* k, DumpTimeClassInfo& info) {
+         if (!k->is_hidden() && !check_for_exclusion(k, &info)) {
+           shared_classes_list.append(k);
+         }
+       }
+     );
+   }
+ 
+   InstanceKlass* ik = vmClasses::Class_klass();
+   objArrayOop r = oopFactory::new_objArray(ik, shared_classes_list.length(), CHECK);
+   objArrayHandle array_h(THREAD, r);
+ 
+   for (int i = 0; i < shared_classes_list.length(); i++) {
+     oop mirror = shared_classes_list.at(i)->java_mirror();
+     Handle mirror_h(THREAD, mirror);
+     array_h->obj_at_put(i, mirror_h());
+   }
+ 
+   TempNewSymbol method = SymbolTable::new_symbol("generatePositiveLookupCache");
+   TempNewSymbol signature = SymbolTable::new_symbol("([Ljava/lang/Class;)V");
+ 
+   JavaCallArguments args(Handle(THREAD, SystemDictionary::java_system_loader()));
+   args.push_oop(array_h);
+   JavaValue result(T_VOID);
+   JavaCalls::call_virtual(&result,
+                           vmClasses::jdk_internal_loader_ClassLoaders_AppClassLoader_klass(),
+                           method,
+                           signature,
+                           &args,
+                           CHECK);
+ 
+   if (HAS_PENDING_EXCEPTION) {
+     Handle exc_handle(THREAD, PENDING_EXCEPTION);
+     CLEAR_PENDING_EXCEPTION;
+     ResourceMark rm(THREAD);
+ 
+     log_warning(cds)("Exception during AppClassLoader::generatePositiveLookupCache() call");
+     LogStreamHandle(Debug, cds) log;
+     if (log.is_enabled()) {
+       java_lang_Throwable::print_stack_trace(exc_handle, &log);
+     }
+     return;
+   }
+ }
< prev index next >