8209545: Simplify HeapShared::archive_module_graph_objects
authoriklam
Wed, 15 Aug 2018 11:19:57 -0700
changeset 51429 d9f6e3ee7fcb
parent 51428 211998500d39
child 51430 e2ced90cbd36
8209545: Simplify HeapShared::archive_module_graph_objects Summary: Added archivable_static_fields array in heapShared.cpp Reviewed-by: jiangli
src/hotspot/share/classfile/javaClasses.cpp
src/hotspot/share/classfile/javaClasses.hpp
src/hotspot/share/classfile/systemDictionary.hpp
src/hotspot/share/classfile/vmSymbols.hpp
src/hotspot/share/memory/heapShared.cpp
src/hotspot/share/memory/heapShared.hpp
src/hotspot/share/memory/metaspaceShared.cpp
--- a/src/hotspot/share/classfile/javaClasses.cpp	Thu Aug 16 19:49:25 2018 -0400
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Wed Aug 15 11:19:57 2018 -0700
@@ -4248,15 +4248,7 @@
 int java_util_concurrent_locks_AbstractOwnableSynchronizer::_owner_offset;
 int reflect_ConstantPool::_oop_offset;
 int reflect_UnsafeStaticFieldAccessorImpl::_base_offset;
-int jdk_internal_module_ArchivedModuleGraph::_archivedSystemModules_offset;
-int jdk_internal_module_ArchivedModuleGraph::_archivedModuleFinder_offset;
-int jdk_internal_module_ArchivedModuleGraph::_archivedMainModule_offset;
-int jdk_internal_module_ArchivedModuleGraph::_archivedConfiguration_offset;
-int java_lang_Integer_IntegerCache::_archivedCache_offset;
-int java_lang_module_Configuration::_EMPTY_CONFIGURATION_offset;
-int java_util_ImmutableCollections_ListN::_EMPTY_LIST_offset;
-int java_util_ImmutableCollections_SetN::_EMPTY_SET_offset;
-int java_util_ImmutableCollections_MapN::_EMPTY_MAP_offset;
+
 
 #define STACKTRACEELEMENT_FIELDS_DO(macro) \
   macro(declaringClassObject_offset,  k, "declaringClassObject", class_signature, false); \
@@ -4419,99 +4411,6 @@
   return (hardcoded_offset * heapOopSize) + instanceOopDesc::base_offset_in_bytes();
 }
 
-#define INTEGERCACHE_FIELDS_DO(macro) \
-  macro(_archivedCache_offset,  k, "archivedCache",  java_lang_Integer_array_signature, true)
-
-void java_lang_Integer_IntegerCache::compute_offsets() {
-  InstanceKlass* k = SystemDictionary::Integer_IntegerCache_klass();
-  assert(k != NULL, "must be loaded");
-  INTEGERCACHE_FIELDS_DO(FIELD_COMPUTE_OFFSET);
-}
-
-#if INCLUDE_CDS
-void java_lang_Integer_IntegerCache::serialize_offsets(SerializeClosure* f) {
-  INTEGERCACHE_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
-}
-#endif
-
-#define ARCHIVEDMODULEGRAPH_FIELDS_DO(macro) \
-  macro(_archivedSystemModules_offset,      k, "archivedSystemModules", systemModules_signature, true); \
-  macro(_archivedModuleFinder_offset,       k, "archivedModuleFinder",  moduleFinder_signature,  true); \
-  macro(_archivedMainModule_offset,         k, "archivedMainModule",    string_signature,        true); \
-  macro(_archivedConfiguration_offset,      k, "archivedConfiguration", configuration_signature, true)
-
-void jdk_internal_module_ArchivedModuleGraph::compute_offsets() {
-  InstanceKlass* k = SystemDictionary::ArchivedModuleGraph_klass();
-  assert(k != NULL, "must be loaded");
-  ARCHIVEDMODULEGRAPH_FIELDS_DO(FIELD_COMPUTE_OFFSET);
-}
-
-#if INCLUDE_CDS
-void jdk_internal_module_ArchivedModuleGraph::serialize_offsets(SerializeClosure* f) {
-  ARCHIVEDMODULEGRAPH_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
-}
-#endif
-
-#define CONFIGURATION_FIELDS_DO(macro) \
-  macro(_EMPTY_CONFIGURATION_offset, k, "EMPTY_CONFIGURATION", configuration_signature, true)
-
-void java_lang_module_Configuration::compute_offsets() {
-  InstanceKlass* k = SystemDictionary::Configuration_klass();
-  assert(k != NULL, "must be loaded");
-  CONFIGURATION_FIELDS_DO(FIELD_COMPUTE_OFFSET);
-}
-
-#if INCLUDE_CDS
-void java_lang_module_Configuration::serialize_offsets(SerializeClosure* f) {
-  CONFIGURATION_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
-}
-#endif
-
-#define LISTN_FIELDS_DO(macro) \
-  macro(_EMPTY_LIST_offset, k, "EMPTY_LIST", list_signature, true)
-
-void java_util_ImmutableCollections_ListN::compute_offsets() {
-  InstanceKlass* k = SystemDictionary::ImmutableCollections_ListN_klass();
-  assert(k != NULL, "must be loaded");
-  LISTN_FIELDS_DO(FIELD_COMPUTE_OFFSET);
-}
-
-#if INCLUDE_CDS
-void java_util_ImmutableCollections_ListN::serialize_offsets(SerializeClosure* f) {
-  LISTN_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
-}
-#endif
-
-#define SETN_FIELDS_DO(macro) \
-  macro(_EMPTY_SET_offset, k, "EMPTY_SET", set_signature, true)
-
-void java_util_ImmutableCollections_SetN::compute_offsets() {
-  InstanceKlass* k = SystemDictionary::ImmutableCollections_SetN_klass();
-  assert(k != NULL, "must be loaded");
-  SETN_FIELDS_DO(FIELD_COMPUTE_OFFSET);
-}
-
-#if INCLUDE_CDS
-void java_util_ImmutableCollections_SetN::serialize_offsets(SerializeClosure* f) {
-  SETN_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
-}
-#endif
-
-#define MAPN_FIELDS_DO(macro) \
-  macro(_EMPTY_MAP_offset, k, "EMPTY_MAP", map_signature, true)
-
-void java_util_ImmutableCollections_MapN::compute_offsets() {
-  InstanceKlass* k = SystemDictionary::ImmutableCollections_MapN_klass();
-  assert(k != NULL, "must be loaded");
-  MAPN_FIELDS_DO(FIELD_COMPUTE_OFFSET);
-}
-
-#if INCLUDE_CDS
-void java_util_ImmutableCollections_MapN::serialize_offsets(SerializeClosure* f) {
-  MAPN_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
-}
-#endif
-
 // Compute hard-coded offsets
 // Invoked before SystemDictionary::initialize, so pre-loaded classes
 // are not available to determine the offset_of_static_fields.
--- a/src/hotspot/share/classfile/javaClasses.hpp	Thu Aug 16 19:49:25 2018 -0400
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Wed Aug 15 11:19:57 2018 -0700
@@ -82,12 +82,6 @@
   f(java_lang_StackFrameInfo) \
   f(java_lang_LiveStackFrameInfo) \
   f(java_util_concurrent_locks_AbstractOwnableSynchronizer) \
-  f(jdk_internal_module_ArchivedModuleGraph) \
-  f(java_lang_Integer_IntegerCache) \
-  f(java_lang_module_Configuration) \
-  f(java_util_ImmutableCollections_ListN) \
-  f(java_util_ImmutableCollections_MapN) \
-  f(java_util_ImmutableCollections_SetN) \
   //end
 
 #define BASIC_JAVA_CLASSES_DO(f) \
@@ -1531,66 +1525,6 @@
   static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
 };
 
-class java_lang_Integer_IntegerCache: AllStatic {
- private:
-  static int _archivedCache_offset;
- public:
-  static int archivedCache_offset()  { return _archivedCache_offset; }
-  static void compute_offsets();
-  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
-};
-
-class jdk_internal_module_ArchivedModuleGraph: AllStatic {
- private:
-  static int _archivedSystemModules_offset;
-  static int _archivedModuleFinder_offset;
-  static int _archivedMainModule_offset;
-  static int _archivedConfiguration_offset;
- public:
-  static int  archivedSystemModules_offset()      { return _archivedSystemModules_offset; }
-  static int  archivedModuleFinder_offset()       { return _archivedModuleFinder_offset; }
-  static int  archivedMainModule_offset()         { return _archivedMainModule_offset; }
-  static int  archivedConfiguration_offset()      { return _archivedConfiguration_offset; }
-  static void compute_offsets();
-  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
-};
-
-class java_lang_module_Configuration: AllStatic {
- private:
-  static int _EMPTY_CONFIGURATION_offset;
- public:
-  static int EMPTY_CONFIGURATION_offset() { return _EMPTY_CONFIGURATION_offset; }
-  static void compute_offsets();
-  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
-};
-
-class java_util_ImmutableCollections_ListN : AllStatic {
- private:
-  static int _EMPTY_LIST_offset;
- public:
-  static int EMPTY_LIST_offset() { return _EMPTY_LIST_offset; }
-  static void compute_offsets();
-  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
-};
-
-class java_util_ImmutableCollections_SetN : AllStatic {
- private:
-  static int _EMPTY_SET_offset;
- public:
-  static int EMPTY_SET_offset() { return _EMPTY_SET_offset; }
-  static void compute_offsets();
-  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
-};
-
-class java_util_ImmutableCollections_MapN : AllStatic {
- private:
-  static int _EMPTY_MAP_offset;
- public:
-  static int EMPTY_MAP_offset() { return _EMPTY_MAP_offset; }
-  static void compute_offsets();
-  static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
-};
-
 // Use to declare fields that need to be injected into Java classes
 // for the JVM to use.  The name_index and signature_index are
 // declared in vmSymbols.  The may_be_java flag is used to declare
--- a/src/hotspot/share/classfile/systemDictionary.hpp	Thu Aug 16 19:49:25 2018 -0400
+++ b/src/hotspot/share/classfile/systemDictionary.hpp	Wed Aug 15 11:19:57 2018 -0700
@@ -187,11 +187,6 @@
   do_klass(jdk_internal_loader_ClassLoaders_AppClassLoader_klass,      jdk_internal_loader_ClassLoaders_AppClassLoader,       Pre ) \
   do_klass(jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass, jdk_internal_loader_ClassLoaders_PlatformClassLoader,  Pre ) \
   do_klass(CodeSource_klass,                            java_security_CodeSource,                  Pre                 ) \
-  do_klass(Configuration_klass,                         java_lang_module_Configuration,            Pre                 ) \
-  do_klass(ImmutableCollections_ListN_klass,            java_util_ImmutableCollections_ListN,      Pre                 ) \
-  do_klass(ImmutableCollections_MapN_klass,             java_util_ImmutableCollections_MapN,       Pre                 ) \
-  do_klass(ImmutableCollections_SetN_klass,             java_util_ImmutableCollections_SetN,       Pre                 ) \
-  do_klass(ArchivedModuleGraph_klass,                   jdk_internal_module_ArchivedModuleGraph,   Pre                 ) \
                                                                                                                          \
   do_klass(StackTraceElement_klass,                     java_lang_StackTraceElement,               Opt                 ) \
                                                                                                                          \
@@ -215,7 +210,6 @@
   do_klass(Byte_klass,                                  java_lang_Byte,                            Pre                 ) \
   do_klass(Short_klass,                                 java_lang_Short,                           Pre                 ) \
   do_klass(Integer_klass,                               java_lang_Integer,                         Pre                 ) \
-  do_klass(Integer_IntegerCache_klass,                  java_lang_Integer_IntegerCache,            Pre                 ) \
   do_klass(Long_klass,                                  java_lang_Long,                            Pre                 ) \
                                                                                                                          \
   /* JVMCI classes. These are loaded on-demand. */                                                                       \
--- a/src/hotspot/share/classfile/vmSymbols.hpp	Thu Aug 16 19:49:25 2018 -0400
+++ b/src/hotspot/share/classfile/vmSymbols.hpp	Wed Aug 15 11:19:57 2018 -0700
@@ -124,7 +124,6 @@
   template(getBootClassPathEntryForClass_name,        "getBootClassPathEntryForClass")            \
   template(jdk_internal_vm_PostVMInitHook,            "jdk/internal/vm/PostVMInitHook")           \
   template(sun_net_www_ParseUtil,                     "sun/net/www/ParseUtil")                    \
-  template(jdk_internal_module_ArchivedModuleGraph,   "jdk/internal/module/ArchivedModuleGraph")  \
                                                                                                   \
   template(jdk_internal_loader_ClassLoaders_AppClassLoader,      "jdk/internal/loader/ClassLoaders$AppClassLoader")      \
   template(jdk_internal_loader_ClassLoaders_PlatformClassLoader, "jdk/internal/loader/ClassLoaders$PlatformClassLoader") \
@@ -649,17 +648,7 @@
   JFR_TEMPLATES(template)                                                                                         \
                                                                                                                   \
   /* cds */                                                                                                       \
-  template(configuration_signature,                "Ljava/lang/module/Configuration;")                            \
-  template(java_lang_module_Configuration,         "java/lang/module/Configuration")                              \
-  template(java_util_ImmutableCollections_ListN,   "java/util/ImmutableCollections$ListN")                        \
-  template(java_util_ImmutableCollections_MapN,    "java/util/ImmutableCollections$MapN")                         \
-  template(java_util_ImmutableCollections_SetN,    "java/util/ImmutableCollections$SetN")                         \
   template(jdk_internal_loader_ClassLoaders,       "jdk/internal/loader/ClassLoaders")                            \
-  template(list_signature,                         "Ljava/util/List;")                                            \
-  template(map_signature,                          "Ljava/util/Map;")                                             \
-  template(moduleFinder_signature,                 "Ljava/lang/module/ModuleFinder;")                             \
-  template(set_signature,                          "Ljava/util/Set;")                                             \
-  template(systemModules_signature,                "Ljdk/internal/module/SystemModules;")                         \
   template(toFileURL_name,                         "toFileURL")                                                   \
   template(toFileURL_signature,                    "(Ljava/lang/String;)Ljava/net/URL;")                          \
   template(url_void_signature,                     "(Ljava/net/URL;)V")                                           \
--- a/src/hotspot/share/memory/heapShared.cpp	Thu Aug 16 19:49:25 2018 -0400
+++ b/src/hotspot/share/memory/heapShared.cpp	Wed Aug 15 11:19:57 2018 -0700
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/javaClasses.inline.hpp"
+#include "classfile/symbolTable.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "logging/log.hpp"
 #include "logging/logMessage.hpp"
@@ -36,6 +37,7 @@
 #include "memory/resourceArea.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/fieldDescriptor.hpp"
 
 #if INCLUDE_CDS_JAVA_HEAP
 KlassSubGraphInfo* HeapShared::_subgraph_info_list = NULL;
@@ -476,7 +478,7 @@
     return;
   }
 
-  if (field_type == T_OBJECT) {
+  if (field_type == T_OBJECT || field_type == T_ARRAY) {
     // obtain k's subGraph Info
     KlassSubGraphInfo* subgraph_info = get_subgraph_info(k);
 
@@ -526,18 +528,77 @@
   }
 }
 
-#define do_module_object_graph(archive_object_graph_do) \
-  archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedSystemModules_offset(), T_OBJECT, CHECK); \
-  archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedModuleFinder_offset(), T_OBJECT, CHECK); \
-  archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedMainModule_offset(), T_OBJECT, CHECK); \
-  archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedConfiguration_offset(), T_OBJECT, CHECK); \
-  archive_object_graph_do(SystemDictionary::ImmutableCollections_ListN_klass(), java_util_ImmutableCollections_ListN::EMPTY_LIST_offset(), T_OBJECT, CHECK); \
-  archive_object_graph_do(SystemDictionary::ImmutableCollections_MapN_klass(),  java_util_ImmutableCollections_MapN::EMPTY_MAP_offset(), T_OBJECT, CHECK); \
-  archive_object_graph_do(SystemDictionary::ImmutableCollections_SetN_klass(),  java_util_ImmutableCollections_SetN::EMPTY_SET_offset(), T_OBJECT, CHECK); \
-  archive_object_graph_do(SystemDictionary::Integer_IntegerCache_klass(), java_lang_Integer_IntegerCache::archivedCache_offset(), T_OBJECT, CHECK); \
-  archive_object_graph_do(SystemDictionary::Configuration_klass(),       java_lang_module_Configuration::EMPTY_CONFIGURATION_offset(), T_OBJECT, CHECK)
+struct ArchivableStaticFieldInfo {
+  const char* class_name;
+  const char* field_name;
+  InstanceKlass* klass;
+  int offset;
+  BasicType type;
+};
+
+// If you add new entries to this table, you should know what you're doing!
+static ArchivableStaticFieldInfo archivable_static_fields[] = {
+  {"jdk/internal/module/ArchivedModuleGraph",  "archivedSystemModules"},
+  {"jdk/internal/module/ArchivedModuleGraph",  "archivedModuleFinder"},
+  {"jdk/internal/module/ArchivedModuleGraph",  "archivedMainModule"},
+  {"jdk/internal/module/ArchivedModuleGraph",  "archivedConfiguration"},
+  {"java/util/ImmutableCollections$ListN",     "EMPTY_LIST"},
+  {"java/util/ImmutableCollections$MapN",      "EMPTY_MAP"},
+  {"java/util/ImmutableCollections$SetN",      "EMPTY_SET"},
+  {"java/lang/Integer$IntegerCache",           "archivedCache"},
+  {"java/lang/module/Configuration",           "EMPTY_CONFIGURATION"},
+};
+
+const static int num_archivable_static_fields = sizeof(archivable_static_fields) / sizeof(ArchivableStaticFieldInfo);
+
+class ArchivableStaticFieldFinder: public FieldClosure {
+  InstanceKlass* _ik;
+  Symbol* _field_name;
+  bool _found;
+  int _offset;
+  BasicType _type;
+public:
+  ArchivableStaticFieldFinder(InstanceKlass* ik, Symbol* field_name) :
+    _ik(ik), _field_name(field_name), _found(false), _offset(-1), _type(T_ILLEGAL) {}
+
+  virtual void do_field(fieldDescriptor* fd) {
+    if (fd->name() == _field_name) {
+      assert(!_found, "fields cannot be overloaded");
+      _found = true;
+      _offset = fd->offset();
+      _type = fd->field_type();
+      assert(_type == T_OBJECT || _type == T_ARRAY, "can archive only obj or array fields");
+    }
+  }
+  bool found()     { return _found;  }
+  int offset()     { return _offset; }
+  BasicType type() { return _type;   }
+};
+
+void HeapShared::init_archivable_static_fields(Thread* THREAD) {
+  for (int i = 0; i < num_archivable_static_fields; i++) {
+    ArchivableStaticFieldInfo* info = &archivable_static_fields[i];
+    TempNewSymbol class_name =  SymbolTable::new_symbol(info->class_name, THREAD);
+    TempNewSymbol field_name =  SymbolTable::new_symbol(info->field_name, THREAD);
+
+    Klass* k = SystemDictionary::resolve_or_null(class_name, THREAD);
+    assert(k != NULL && !HAS_PENDING_EXCEPTION, "class must exist");
+    InstanceKlass* ik = InstanceKlass::cast(k);
+
+    ArchivableStaticFieldFinder finder(ik, field_name);
+    ik->do_local_static_fields(&finder);
+    assert(finder.found(), "field must exist");
+
+    info->klass = ik;
+    info->offset = finder.offset();
+    info->type = finder.type();
+  }
+}
 
 void HeapShared::archive_module_graph_objects(Thread* THREAD) {
-  do_module_object_graph(archive_reachable_objects_from_static_field);
+  for (int i = 0; i < num_archivable_static_fields; i++) {
+    ArchivableStaticFieldInfo* info = &archivable_static_fields[i];
+    archive_reachable_objects_from_static_field(info->klass, info->offset, info->type, CHECK);
+  }
 }
 #endif // INCLUDE_CDS_JAVA_HEAP
--- a/src/hotspot/share/memory/heapShared.hpp	Thu Aug 16 19:49:25 2018 -0400
+++ b/src/hotspot/share/memory/heapShared.hpp	Wed Aug 15 11:19:57 2018 -0700
@@ -129,6 +129,7 @@
   static void write_archived_subgraph_infos() NOT_CDS_JAVA_HEAP_RETURN;
   static void initialize_from_archived_subgraph(Klass* k) NOT_CDS_JAVA_HEAP_RETURN;
 
+  static void init_archivable_static_fields(Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN;
   static void archive_module_graph_objects(Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN;
 };
 #endif // SHARE_VM_MEMORY_HEAPSHARED_HPP
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Thu Aug 16 19:49:25 2018 -0400
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Wed Aug 15 11:19:57 2018 -0700
@@ -1698,6 +1698,7 @@
     tty->print_cr("Rewriting and linking classes: done");
 
     SystemDictionary::clear_invoke_method_table();
+    HeapShared::init_archivable_static_fields(THREAD);
 
     VM_PopulateDumpSharedSpace op;
     VMThread::execute(&op);