< prev index next >

src/hotspot/share/memory/metaspace.cpp

Print this page
rev 49232 : imported patch 8199431-split-class-metaspace-into-two-parts
rev 49233 : imported patch 8199431-split-class-metaspace-into-two-parts-coleen1
rev 49234 : imported patch 8199431-split-class-metaspace-into-two-parts-coleen2

@@ -4333,21 +4333,10 @@
 size_t Metaspace::_first_class_chunk_word_size = 0;
 
 size_t Metaspace::_commit_alignment = 0;
 size_t Metaspace::_reserve_alignment = 0;
 
-ClassLoaderMetaspace::ClassLoaderMetaspace(Mutex* lock, Metaspace::MetaspaceType type) {
-  initialize(lock, type);
-}
-
-ClassLoaderMetaspace::~ClassLoaderMetaspace() {
-  delete _vsm;
-  if (Metaspace::using_class_space()) {
-    delete _class_vsm;
-  }
-}
-
 VirtualSpaceList* Metaspace::_space_list = NULL;
 VirtualSpaceList* Metaspace::_class_space_list = NULL;
 
 ChunkManager* Metaspace::_chunk_manager_metadata = NULL;
 ChunkManager* Metaspace::_chunk_manager_class = NULL;

@@ -4678,10 +4667,172 @@
 
 void Metaspace::post_initialize() {
   MetaspaceGC::post_initialize();
 }
 
+void Metaspace::verify_global_initialization() {
+  assert(space_list() != NULL, "Metadata VirtualSpaceList has not been initialized");
+  assert(chunk_manager_metadata() != NULL, "Metadata ChunkManager has not been initialized");
+
+  if (using_class_space()) {
+    assert(class_space_list() != NULL, "Class VirtualSpaceList has not been initialized");
+    assert(chunk_manager_class() != NULL, "Class ChunkManager has not been initialized");
+  }
+}
+
+size_t Metaspace::align_word_size_up(size_t word_size) {
+  size_t byte_size = word_size * wordSize;
+  return ReservedSpace::allocation_align_size_up(byte_size) / wordSize;
+}
+
+MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
+                              MetaspaceObj::Type type, TRAPS) {
+  assert(!_frozen, "sanity");
+  if (HAS_PENDING_EXCEPTION) {
+    assert(false, "Should not allocate with exception pending");
+    return NULL;  // caller does a CHECK_NULL too
+  }
+
+  assert(loader_data != NULL, "Should never pass around a NULL loader_data. "
+        "ClassLoaderData::the_null_class_loader_data() should have been used.");
+
+  MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType;
+
+  // Try to allocate metadata.
+  MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
+
+  if (result == NULL) {
+    if (DumpSharedSpaces && THREAD->is_VM_thread()) {
+      tty->print_cr("Failed allocating metaspace object type %s of size " SIZE_FORMAT ". CDS dump aborted.",
+          MetaspaceObj::type_name(type), word_size * BytesPerWord);
+      vm_exit(1);
+    }
+
+    tracer()->report_metaspace_allocation_failure(loader_data, word_size, type, mdtype);
+
+    // Allocation failed.
+    if (is_init_completed()) {
+      // Only start a GC if the bootstrapping has completed.
+
+      // Try to clean out some memory and retry.
+      result = Universe::heap()->satisfy_failed_metadata_allocation(loader_data, word_size, mdtype);
+    }
+  }
+
+  if (result == NULL) {
+    report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL);
+  }
+
+  // Zero initialize.
+  Copy::fill_to_words((HeapWord*)result, word_size, 0);
+
+  return result;
+}
+
+void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_size, MetaspaceObj::Type type, MetadataType mdtype, TRAPS) {
+  tracer()->report_metadata_oom(loader_data, word_size, type, mdtype);
+
+  // If result is still null, we are out of memory.
+  Log(gc, metaspace, freelist) log;
+  if (log.is_info()) {
+    log.info("Metaspace (%s) allocation failed for size " SIZE_FORMAT,
+             is_class_space_allocation(mdtype) ? "class" : "data", word_size);
+    ResourceMark rm;
+    if (log.is_debug()) {
+      if (loader_data->metaspace_or_null() != NULL) {
+        LogStream ls(log.debug());
+        loader_data->print_value_on(&ls);
+      }
+    }
+    LogStream ls(log.info());
+    MetaspaceUtils::dump(&ls);
+    MetaspaceUtils::print_metaspace_map(&ls, mdtype);
+    ChunkManager::print_all_chunkmanagers(&ls);
+  }
+
+  bool out_of_compressed_class_space = false;
+  if (is_class_space_allocation(mdtype)) {
+    ClassLoaderMetaspace* metaspace = loader_data->metaspace_non_null();
+    out_of_compressed_class_space =
+      MetaspaceUtils::committed_bytes(Metaspace::ClassType) +
+      (metaspace->class_chunk_size(word_size) * BytesPerWord) >
+      CompressedClassSpaceSize;
+  }
+
+  // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
+  const char* space_string = out_of_compressed_class_space ?
+    "Compressed class space" : "Metaspace";
+
+  report_java_out_of_memory(space_string);
+
+  if (JvmtiExport::should_post_resource_exhausted()) {
+    JvmtiExport::post_resource_exhausted(
+        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
+        space_string);
+  }
+
+  if (!is_init_completed()) {
+    vm_exit_during_initialization("OutOfMemoryError", space_string);
+  }
+
+  if (out_of_compressed_class_space) {
+    THROW_OOP(Universe::out_of_memory_error_class_metaspace());
+  } else {
+    THROW_OOP(Universe::out_of_memory_error_metaspace());
+  }
+}
+
+const char* Metaspace::metadata_type_name(Metaspace::MetadataType mdtype) {
+  switch (mdtype) {
+    case Metaspace::ClassType: return "Class";
+    case Metaspace::NonClassType: return "Metadata";
+    default:
+      assert(false, "Got bad mdtype: %d", (int) mdtype);
+      return NULL;
+  }
+}
+
+void Metaspace::purge(MetadataType mdtype) {
+  get_space_list(mdtype)->purge(get_chunk_manager(mdtype));
+}
+
+void Metaspace::purge() {
+  MutexLockerEx cl(SpaceManager::expand_lock(),
+                   Mutex::_no_safepoint_check_flag);
+  purge(NonClassType);
+  if (using_class_space()) {
+    purge(ClassType);
+  }
+}
+
+bool Metaspace::contains(const void* ptr) {
+  if (MetaspaceShared::is_in_shared_metaspace(ptr)) {
+    return true;
+  }
+  return contains_non_shared(ptr);
+}
+
+bool Metaspace::contains_non_shared(const void* ptr) {
+  if (using_class_space() && get_space_list(ClassType)->contains(ptr)) {
+     return true;
+  }
+
+  return get_space_list(NonClassType)->contains(ptr);
+}
+
+// ClassLoaderMetaspace
+
+ClassLoaderMetaspace::ClassLoaderMetaspace(Mutex* lock, Metaspace::MetaspaceType type) {
+  initialize(lock, type);
+}
+
+ClassLoaderMetaspace::~ClassLoaderMetaspace() {
+  delete _vsm;
+  if (Metaspace::using_class_space()) {
+    delete _class_vsm;
+  }
+}
 void ClassLoaderMetaspace::initialize_first_chunk(Metaspace::MetaspaceType type, Metaspace::MetadataType mdtype) {
   Metachunk* chunk = get_initialization_chunk(type, mdtype);
   if (chunk != NULL) {
     // Add to this manager's list of chunks in use and current_chunk().
     get_space_manager(mdtype)->add_chunk(chunk, true);

@@ -4700,20 +4851,10 @@
   }
 
   return chunk;
 }
 
-void Metaspace::verify_global_initialization() {
-  assert(space_list() != NULL, "Metadata VirtualSpaceList has not been initialized");
-  assert(chunk_manager_metadata() != NULL, "Metadata ChunkManager has not been initialized");
-
-  if (using_class_space()) {
-    assert(class_space_list() != NULL, "Class VirtualSpaceList has not been initialized");
-    assert(chunk_manager_class() != NULL, "Class ChunkManager has not been initialized");
-  }
-}
-
 void ClassLoaderMetaspace::initialize(Mutex* lock, Metaspace::MetaspaceType type) {
   Metaspace::verify_global_initialization();
 
   // Allocate SpaceManager for metadata objects.
   _vsm = new SpaceManager(Metaspace::NonClassType, type, lock);

@@ -4732,15 +4873,10 @@
   if (Metaspace::using_class_space()) {
     initialize_first_chunk(type, Metaspace::ClassType);
   }
 }
 
-size_t Metaspace::align_word_size_up(size_t word_size) {
-  size_t byte_size = word_size * wordSize;
-  return ReservedSpace::allocation_align_size_up(byte_size) / wordSize;
-}
-
 MetaWord* ClassLoaderMetaspace::allocate(size_t word_size, Metaspace::MetadataType mdtype) {
   Metaspace::assert_not_frozen();
   // Don't use class_vsm() unless UseCompressedClassPointers is true.
   if (Metaspace::is_class_space_allocation(mdtype)) {
     return  class_vsm()->allocate(word_size);

@@ -4836,160 +4972,25 @@
   } else {
     vsm()->deallocate(ptr, word_size);
   }
 }
 
-MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
-                              MetaspaceObj::Type type, TRAPS) {
-  assert(!_frozen, "sanity");
-  if (HAS_PENDING_EXCEPTION) {
-    assert(false, "Should not allocate with exception pending");
-    return NULL;  // caller does a CHECK_NULL too
-  }
-
-  assert(loader_data != NULL, "Should never pass around a NULL loader_data. "
-        "ClassLoaderData::the_null_class_loader_data() should have been used.");
-
-  MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType;
-
-  // Try to allocate metadata.
-  MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
-
-  if (result == NULL) {
-    if (DumpSharedSpaces && THREAD->is_VM_thread()) {
-      tty->print_cr("Failed allocating metaspace object type %s of size " SIZE_FORMAT ". CDS dump aborted.",
-          MetaspaceObj::type_name(type), word_size * BytesPerWord);
-      vm_exit(1);
-    }
-
-    tracer()->report_metaspace_allocation_failure(loader_data, word_size, type, mdtype);
-
-    // Allocation failed.
-    if (is_init_completed()) {
-      // Only start a GC if the bootstrapping has completed.
-
-      // Try to clean out some memory and retry.
-      result = Universe::heap()->satisfy_failed_metadata_allocation(loader_data, word_size, mdtype);
-    }
-  }
-
-  if (result == NULL) {
-    report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL);
-  }
-
-  // Zero initialize.
-  Copy::fill_to_words((HeapWord*)result, word_size, 0);
-
-  return result;
-}
-
 size_t ClassLoaderMetaspace::class_chunk_size(size_t word_size) {
   assert(Metaspace::using_class_space(), "Has to use class space");
   return class_vsm()->calc_chunk_size(word_size);
 }
 
-void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_size, MetaspaceObj::Type type, MetadataType mdtype, TRAPS) {
-  tracer()->report_metadata_oom(loader_data, word_size, type, mdtype);
-
-  // If result is still null, we are out of memory.
-  Log(gc, metaspace, freelist) log;
-  if (log.is_info()) {
-    log.info("Metaspace (%s) allocation failed for size " SIZE_FORMAT,
-             is_class_space_allocation(mdtype) ? "class" : "data", word_size);
-    ResourceMark rm;
-    if (log.is_debug()) {
-      if (loader_data->metaspace_or_null() != NULL) {
-        LogStream ls(log.debug());
-        loader_data->print_value_on(&ls);
-      }
-    }
-    LogStream ls(log.info());
-    MetaspaceUtils::dump(&ls);
-    MetaspaceUtils::print_metaspace_map(&ls, mdtype);
-    ChunkManager::print_all_chunkmanagers(&ls);
-  }
-
-  bool out_of_compressed_class_space = false;
-  if (is_class_space_allocation(mdtype)) {
-    ClassLoaderMetaspace* metaspace = loader_data->metaspace_non_null();
-    out_of_compressed_class_space =
-      MetaspaceUtils::committed_bytes(Metaspace::ClassType) +
-      (metaspace->class_chunk_size(word_size) * BytesPerWord) >
-      CompressedClassSpaceSize;
-  }
-
-  // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
-  const char* space_string = out_of_compressed_class_space ?
-    "Compressed class space" : "Metaspace";
-
-  report_java_out_of_memory(space_string);
-
-  if (JvmtiExport::should_post_resource_exhausted()) {
-    JvmtiExport::post_resource_exhausted(
-        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
-        space_string);
-  }
-
-  if (!is_init_completed()) {
-    vm_exit_during_initialization("OutOfMemoryError", space_string);
-  }
-
-  if (out_of_compressed_class_space) {
-    THROW_OOP(Universe::out_of_memory_error_class_metaspace());
-  } else {
-    THROW_OOP(Universe::out_of_memory_error_metaspace());
-  }
-}
-
-const char* Metaspace::metadata_type_name(Metaspace::MetadataType mdtype) {
-  switch (mdtype) {
-    case Metaspace::ClassType: return "Class";
-    case Metaspace::NonClassType: return "Metadata";
-    default:
-      assert(false, "Got bad mdtype: %d", (int) mdtype);
-      return NULL;
-  }
-}
-
-void Metaspace::purge(MetadataType mdtype) {
-  get_space_list(mdtype)->purge(get_chunk_manager(mdtype));
-}
-
-void Metaspace::purge() {
-  MutexLockerEx cl(SpaceManager::expand_lock(),
-                   Mutex::_no_safepoint_check_flag);
-  purge(NonClassType);
-  if (using_class_space()) {
-    purge(ClassType);
-  }
-}
-
 void ClassLoaderMetaspace::print_on(outputStream* out) const {
   // Print both class virtual space counts and metaspace.
   if (Verbose) {
     vsm()->print_on(out);
     if (Metaspace::using_class_space()) {
       class_vsm()->print_on(out);
     }
   }
 }
 
-bool Metaspace::contains(const void* ptr) {
-  if (MetaspaceShared::is_in_shared_metaspace(ptr)) {
-    return true;
-  }
-  return contains_non_shared(ptr);
-}
-
-bool Metaspace::contains_non_shared(const void* ptr) {
-  if (using_class_space() && get_space_list(ClassType)->contains(ptr)) {
-     return true;
-  }
-
-  return get_space_list(NonClassType)->contains(ptr);
-}
-
 void ClassLoaderMetaspace::verify() {
   vsm()->verify();
   if (Metaspace::using_class_space()) {
     class_vsm()->verify();
   }

@@ -5002,10 +5003,12 @@
     out->print_cr("\nClass space manager: " INTPTR_FORMAT, p2i(class_vsm()));
     class_vsm()->dump(out);
   }
 }
 
+
+
 #ifdef ASSERT
 static void do_verify_chunk(Metachunk* chunk) {
   guarantee(chunk != NULL, "Sanity");
   // Verify chunk itself; then verify that it is consistent with the
   // occupany map of its containing node.
< prev index next >