diff options
Diffstat (limited to 'src/share/vm/memory/metaspace.cpp')
-rw-r--r-- | src/share/vm/memory/metaspace.cpp | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/src/share/vm/memory/metaspace.cpp b/src/share/vm/memory/metaspace.cpp index 7245e4f28..1e83247ad 100644 --- a/src/share/vm/memory/metaspace.cpp +++ b/src/share/vm/memory/metaspace.cpp @@ -36,6 +36,7 @@ #include "memory/universe.hpp" #include "runtime/globals.hpp" #include "runtime/mutex.hpp" +#include "runtime/orderAccess.hpp" #include "services/memTracker.hpp" #include "utilities/copy.hpp" #include "utilities/debug.hpp" @@ -108,7 +109,6 @@ size_t Metablock::_min_block_byte_size = sizeof(Metablock); size_t Metablock::_overhead = 0; #endif - // Pointer to list of Metachunks. class ChunkList VALUE_OBJ_CLASS_SPEC { // List of free chunks @@ -325,10 +325,12 @@ class VirtualSpaceNode : public CHeapObj<mtClass> { bool expand_by(size_t words, bool pre_touch = false); bool shrink_by(size_t words); +#ifdef ASSERT // Debug support static void verify_virtual_space_total(); static void verify_virtual_space_count(); void mangle(); +#endif void print_on(outputStream* st) const; }; @@ -621,8 +623,8 @@ class SpaceManager : public CHeapObj<mtClass> { void locked_print_chunks_in_use_on(outputStream* st) const; void verify(); + NOT_PRODUCT(void mangle_freed_chunks();) #ifdef ASSERT - void mangle_freed_chunks(); void verify_allocation_total(); #endif }; @@ -711,7 +713,7 @@ void Metachunk::print_on(outputStream* st) const { bottom(), top(), end(), word_size()); } -#ifdef ASSERT +#ifndef PRODUCT void Metachunk::mangle() { // Mangle the payload of the chunk and not the links that // maintain list of chunks. @@ -719,7 +721,7 @@ void Metachunk::mangle() { size_t word_size = capacity_word_size() - overhead(); Copy::fill_to_words(start, word_size, metadata_chunk_initialize); } -#endif // ASSERT +#endif // PRODUCT void Metachunk::verify() { #ifdef ASSERT @@ -917,10 +919,12 @@ void VirtualSpaceNode::print_on(outputStream* st) const { vs->high_boundary()); } +#ifdef ASSERT void VirtualSpaceNode::mangle() { size_t word_size = capacity_words_in_vs(); Copy::fill_to_words((HeapWord*) low(), word_size, 0xf1f1f1f1); } +#endif // ASSERT // VirtualSpaceList methods // Space allocated from the VirtualSpace @@ -1007,6 +1011,8 @@ bool VirtualSpaceList::grow_vs(size_t vs_word_size) { delete new_entry; return false; } else { + // ensure lock-free iteration sees fully initialized node + OrderAccess::storestore(); link_vs(new_entry, vs_word_size); return true; } @@ -1096,7 +1102,6 @@ void VirtualSpaceList::print_on(outputStream* st) const { } } -#ifndef PRODUCT bool VirtualSpaceList::contains(const void *ptr) { VirtualSpaceNode* list = virtual_space_list(); VirtualSpaceListIterator iter(list); @@ -1108,7 +1113,6 @@ bool VirtualSpaceList::contains(const void *ptr) { } return false; } -#endif // PRODUCT // MetaspaceGC methods @@ -1985,16 +1989,14 @@ SpaceManager::~SpaceManager() { locked_print_chunks_in_use_on(gclog_or_tty); } + // Mangle freed memory. + NOT_PRODUCT(mangle_freed_chunks();) + // Have to update before the chunks_in_use lists are emptied // below. chunk_manager->inc_free_chunks_total(sum_capacity_in_chunks_in_use(), sum_count_in_chunks_in_use()); -#ifdef ASSERT - // Mangle freed memory. - mangle_freed_chunks(); -#endif // ASSERT - // Add all the chunks in use by this space manager // to the global list of free chunks. @@ -2273,7 +2275,7 @@ void SpaceManager::dump(outputStream* const out) const { " waste " SIZE_FORMAT, curr_total, used, free, capacity, waste); } -#ifdef ASSERT +#ifndef PRODUCT void SpaceManager::mangle_freed_chunks() { for (ChunkIndex index = SmallIndex; index < NumberOfInUseLists; @@ -2291,11 +2293,16 @@ void SpaceManager::mangle_freed_chunks() { } } } -#endif // ASSERT +#endif // PRODUCT // MetaspaceAux +size_t MetaspaceAux::used_in_bytes() { + return (Metaspace::class_space_list()->used_words_sum() + + Metaspace::space_list()->used_words_sum()) * BytesPerWord; +} + size_t MetaspaceAux::used_in_bytes(Metaspace::MetadataType mdtype) { size_t used = 0; ClassLoaderDataGraphMetaspaceIterator iter; @@ -2324,6 +2331,11 @@ size_t MetaspaceAux::free_in_bytes(Metaspace::MetadataType mdtype) { // The total words available for metadata allocation. This // uses Metaspace capacity_words() which is the total words // in chunks allocated for a Metaspace. +size_t MetaspaceAux::capacity_in_bytes() { + return (Metaspace::class_space_list()->capacity_words_sum() + + Metaspace::space_list()->capacity_words_sum()) * BytesPerWord; +} + size_t MetaspaceAux::capacity_in_bytes(Metaspace::MetadataType mdtype) { size_t capacity = free_chunks_total(mdtype); ClassLoaderDataGraphMetaspaceIterator iter; @@ -2336,6 +2348,11 @@ size_t MetaspaceAux::capacity_in_bytes(Metaspace::MetadataType mdtype) { return capacity * BytesPerWord; } +size_t MetaspaceAux::reserved_in_bytes() { + return (Metaspace::class_space_list()->virtual_space_total() + + Metaspace::space_list()->virtual_space_total()) * BytesPerWord; +} + size_t MetaspaceAux::reserved_in_bytes(Metaspace::MetadataType mdtype) { size_t reserved = (mdtype == Metaspace::ClassType) ? Metaspace::class_space_list()->virtual_space_total() : @@ -2739,15 +2756,17 @@ void Metaspace::print_on(outputStream* out) const { } } -#ifndef PRODUCT -bool Metaspace::contains(const void * ptr) const { +bool Metaspace::contains(const void * ptr) { if (MetaspaceShared::is_in_shared_space(ptr)) { return true; } - MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); + // This is checked while unlocked. As long as the virtualspaces are added + // at the end, the pointer will be in one of them. The virtual spaces + // aren't deleted presently. When they are, some sort of locking might + // be needed. Note, locking this can cause inversion problems with the + // caller in MetaspaceObj::is_metadata() function. return space_list()->contains(ptr) || class_space_list()->contains(ptr); } -#endif void Metaspace::verify() { vsm()->verify(); |