< prev index next >

src/hotspot/share/classfile/systemDictionary.cpp

Print this page
@@ -21,10 +21,11 @@
   * questions.
   *
   */
  
  #include "precompiled.hpp"
+ #include "cds/aotLinkedClassBulkLoader.hpp"
  #include "cds/cdsConfig.hpp"
  #include "cds/heapShared.hpp"
  #include "classfile/classFileParser.hpp"
  #include "classfile/classFileStream.hpp"
  #include "classfile/classLoader.hpp"

@@ -34,10 +35,11 @@
  #include "classfile/classLoadInfo.hpp"
  #include "classfile/dictionary.hpp"
  #include "classfile/javaClasses.inline.hpp"
  #include "classfile/klassFactory.hpp"
  #include "classfile/loaderConstraints.hpp"
+ #include "classfile/modules.hpp"
  #include "classfile/packageEntry.hpp"
  #include "classfile/placeholders.hpp"
  #include "classfile/protectionDomainCache.hpp"
  #include "classfile/resolutionErrors.hpp"
  #include "classfile/stringTable.hpp"

@@ -80,10 +82,11 @@
  #include "runtime/synchronizer.hpp"
  #include "services/classLoadingService.hpp"
  #include "services/diagnosticCommand.hpp"
  #include "services/finalizerService.hpp"
  #include "services/threadService.hpp"
+ #include "utilities/growableArray.hpp"
  #include "utilities/macros.hpp"
  #include "utilities/utf8.hpp"
  #if INCLUDE_CDS
  #include "classfile/systemDictionaryShared.hpp"
  #endif

@@ -132,33 +135,39 @@
  oop SystemDictionary::java_platform_loader() {
    return _java_platform_loader.resolve();
  }
  
  void SystemDictionary::compute_java_loaders(TRAPS) {
-   if (_java_system_loader.is_empty()) {
-     oop system_loader = get_system_class_loader_impl(CHECK);
-     _java_system_loader = OopHandle(Universe::vm_global(), system_loader);
+   if (_java_platform_loader.is_empty()) {
+     oop platform_loader = get_platform_class_loader_impl(CHECK);
+     _java_platform_loader = OopHandle(Universe::vm_global(), platform_loader);
+     if (CDSConfig::is_dumping_final_static_archive()) {
+       AOTLinkedClassBulkLoader::load_platform_classes(THREAD);
+     }
    } else {
      // It must have been restored from the archived module graph
      assert(CDSConfig::is_using_archive(), "must be");
      assert(CDSConfig::is_using_full_module_graph(), "must be");
      DEBUG_ONLY(
-       oop system_loader = get_system_class_loader_impl(CHECK);
-       assert(_java_system_loader.resolve() == system_loader, "must be");
+       oop platform_loader = get_platform_class_loader_impl(CHECK);
+       assert(_java_platform_loader.resolve() == platform_loader, "must be");
      )
   }
  
-   if (_java_platform_loader.is_empty()) {
-     oop platform_loader = get_platform_class_loader_impl(CHECK);
-     _java_platform_loader = OopHandle(Universe::vm_global(), platform_loader);
+   if (_java_system_loader.is_empty()) {
+     oop system_loader = get_system_class_loader_impl(CHECK);
+     _java_system_loader = OopHandle(Universe::vm_global(), system_loader);
+     if (CDSConfig::is_dumping_final_static_archive()) {
+       AOTLinkedClassBulkLoader::load_app_classes(THREAD);
+     }
    } else {
      // It must have been restored from the archived module graph
      assert(CDSConfig::is_using_archive(), "must be");
      assert(CDSConfig::is_using_full_module_graph(), "must be");
      DEBUG_ONLY(
-       oop platform_loader = get_platform_class_loader_impl(CHECK);
-       assert(_java_platform_loader.resolve() == platform_loader, "must be");
+       oop system_loader = get_system_class_loader_impl(CHECK);
+       assert(_java_system_loader.resolve() == system_loader, "must be");
      )
    }
  }
  
  oop SystemDictionary::get_system_class_loader_impl(TRAPS) {

@@ -1023,11 +1032,15 @@
    ModuleEntry* mod_entry = (pkg_entry == nullptr) ? nullptr : pkg_entry->module();
    bool should_be_in_named_module = (mod_entry != nullptr && mod_entry->is_named());
    bool was_archived_from_named_module = scp_entry->in_named_module();
    bool visible;
  
-   if (was_archived_from_named_module) {
+   if (mod_entry != nullptr && mod_entry->location() == nullptr && mod_entry->is_named()) {
+     // Archived module for dynamic proxies. It's always visible.
+     assert(Modules::is_dynamic_proxy_module(mod_entry), "must be");
+     visible = true;
+   } else if (was_archived_from_named_module) {
      if (should_be_in_named_module) {
        // Is the module loaded from the same location as during dump time?
        visible = mod_entry->shared_path_index() == scp_index;
        if (visible) {
          assert(!mod_entry->is_patched(), "cannot load archived classes for patched module");

@@ -1201,15 +1214,32 @@
  
    // For boot loader, ensure that GetSystemPackage knows that a class in this
    // package was loaded.
    if (loader_data->is_the_null_class_loader_data()) {
      s2 path_index = ik->shared_classpath_index();
-     ik->set_classpath_index(path_index);
+     if (path_index >= 0) { // FIXME ... for lambda form classes
+       ik->set_classpath_index(path_index);
+ 
+       if (CDSConfig::is_dumping_final_static_archive()) {
+         if (path_index > ClassLoaderExt::max_used_path_index()) {
+           ClassLoaderExt::set_max_used_path_index(path_index);
+         }
+       }
+     }
    }
  
    // notify a class loaded from shared object
    ClassLoadingService::notify_class_loaded(ik, true /* shared class */);
+ 
+   if (CDSConfig::is_dumping_final_static_archive()) {
+     SystemDictionaryShared::init_dumptime_info(ik);
+     if (SystemDictionary::is_platform_class_loader(loader_data->class_loader())) {
+       ClassLoaderExt::set_has_platform_classes();
+     } else if (SystemDictionary::is_system_class_loader(loader_data->class_loader())) {
+       ClassLoaderExt::set_has_app_classes();
+     }
+   }
  }
  
  #endif // INCLUDE_CDS
  
  InstanceKlass* SystemDictionary::load_instance_class_impl(Symbol* class_name, Handle class_loader, TRAPS) {

@@ -1280,22 +1310,22 @@
      InstanceKlass* k = nullptr;
  
  #if INCLUDE_CDS
      if (CDSConfig::is_using_archive())
      {
-       PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
+       PerfTraceElapsedTime vmtimer(ClassLoader::perf_shared_classload_time());
        InstanceKlass* ik = SystemDictionaryShared::find_builtin_class(class_name);
        if (ik != nullptr && ik->is_shared_boot_class() && !ik->shared_loading_failed()) {
          SharedClassLoadingMark slm(THREAD, ik);
          k = load_shared_class(ik, class_loader, Handle(), nullptr,  pkg_entry, CHECK_NULL);
        }
      }
  #endif
  
      if (k == nullptr) {
        // Use VM class loader
-       PerfTraceTime vmtimer(ClassLoader::perf_sys_classload_time());
+       PerfTraceElapsedTime vmtimer(ClassLoader::perf_sys_classload_time());
        k = ClassLoader::load_class(class_name, pkg_entry, search_only_bootloader_append, CHECK_NULL);
      }
  
      // find_or_define_instance_class may return a different InstanceKlass
      if (k != nullptr) {

@@ -1718,10 +1748,27 @@
      dictionary->add_klass(current, name, k);
    }
    mu1.notify_all();
  }
  
+ #if INCLUDE_CDS
+ // Indicate that loader_data has initiated the loading of class k, which
+ // has already been defined by a parent loader.
+ // This API should be used only by AOTLinkedClassBulkLoader
+ void SystemDictionary::add_to_initiating_loader(JavaThread* current,
+                                                 InstanceKlass* k,
+                                                 ClassLoaderData* loader_data) {
+   assert(CDSConfig::is_using_aot_linked_classes(), "must be");
+   assert_locked_or_safepoint(SystemDictionary_lock);
+   Symbol* name  = k->name();
+   Dictionary* dictionary = loader_data->dictionary();
+   assert(k->is_loaded(), "must be");
+   assert(k->class_loader_data() != loader_data, "only for classes defined by a parent loader");
+   assert(dictionary->find_class(current, name) == nullptr, "sanity");
+   dictionary->add_klass(current, name, k);
+ }
+ #endif
  
  // Try to find a class name using the loader constraints.  The
  // loader constraints might know about a class that isn't fully loaded
  // yet and these will be ignored.
  Klass* SystemDictionary::find_constrained_instance_or_array_klass(

@@ -2033,10 +2080,50 @@
                     "Out of space in CodeCache for method handle intrinsic");
    }
    return nullptr;
  }
  
+ #if INCLUDE_CDS
+ void SystemDictionary::get_all_method_handle_intrinsics(GrowableArray<Method*>* methods) {
+   auto do_method = [&] (InvokeMethodKey& key, Method*& m) {
+     methods->append(m);
+   };
+   _invoke_method_intrinsic_table->iterate_all(do_method);
+ }
+ 
+ void SystemDictionary::restore_archived_method_handle_intrinsics() {
+   if (UseSharedSpaces) {
+     EXCEPTION_MARK;
+     restore_archived_method_handle_intrinsics_impl(THREAD);
+     if (HAS_PENDING_EXCEPTION) {
+       vm_exit_during_initialization(err_msg("Failed to restore archived method handle intrinsics"));
+     }
+   }
+ }
+ 
+ void SystemDictionary::restore_archived_method_handle_intrinsics_impl(TRAPS) {
+   Array<Method*>* list = MetaspaceShared::archived_method_handle_intrinsics();
+   for (int i = 0; i < list->length(); i++) {
+     methodHandle m(THREAD, list->at(i));
+     Method::restore_archived_method_handle_intrinsic(m, CHECK);
+     m->constants()->restore_unshareable_info(CHECK);
+     if (!Arguments::is_interpreter_only() || m->intrinsic_id() == vmIntrinsics::_linkToNative) {
+       AdapterHandlerLibrary::create_native_wrapper(m);
+       if (!m->has_compiled_code()) {
+         ResourceMark rm(THREAD);
+         vm_exit_during_initialization(err_msg("Failed to initialize method %s", m->external_name()));
+       }
+     }
+ 
+     const int iid_as_int = vmIntrinsics::as_int(m->intrinsic_id());
+     InvokeMethodKey key(m->signature(), iid_as_int);
+     bool created = _invoke_method_intrinsic_table->put(key, m());
+     assert(created, "must be");
+   }
+ }
+ #endif
+ 
  // Helper for unpacking the return value from linkMethod and linkCallSite.
  static Method* unpack_method_and_appendix(Handle mname,
                                            Klass* accessing_klass,
                                            objArrayHandle appendix_box,
                                            Handle* appendix_result,
< prev index next >