< 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 >