# HG changeset patch # User johnc # Date 1353018568 28800 # Node ID c5d4acbb943dfc3e1af10676a18d459a66778851 # Parent 429994fc0754e2388910e707752a8e4726ad3b1c# Parent 0400886d261367c45d999951f18488c2b732ba7c Merge diff -r 429994fc0754 -r c5d4acbb943d src/share/vm/memory/binaryTreeDictionary.cpp --- a/src/share/vm/memory/binaryTreeDictionary.cpp Wed Nov 14 10:13:51 2012 -0800 +++ b/src/share/vm/memory/binaryTreeDictionary.cpp Thu Nov 15 14:29:28 2012 -0800 @@ -239,7 +239,7 @@ } else { if (nextTC == NULL) { // Removing chunk at tail of list - link_tail(prevFC); + this->link_tail(prevFC); } // Chunk is interior to the list prevFC->link_after(nextTC); @@ -296,7 +296,7 @@ Chunk_t* fc = tail(); fc->link_after(chunk); - link_tail(chunk); + this->link_tail(chunk); assert(!tail() || size() == tail()->size(), "Wrong sized chunk in list"); FreeList_t::increment_count(); @@ -323,7 +323,7 @@ chunk->link_after(fc); } else { assert(tail() == NULL, "List is inconsistent"); - link_tail(chunk); + this->link_tail(chunk); } head()->link_after(chunk); assert(!head() || size() == head()->size(), "Wrong sized chunk in list"); @@ -940,7 +940,7 @@ void do_tree(TreeList* tl) { if (tl != NULL) { do_tree(tl->left()); - do_list(tl); + this->do_list(tl); do_tree(tl->right()); } } @@ -952,7 +952,7 @@ void do_tree(TreeList* tl) { if (tl != NULL) { do_tree(tl->right()); - do_list(tl); + this->do_list(tl); do_tree(tl->left()); } } @@ -1022,7 +1022,7 @@ bool do_tree(TreeList* tl) { if (tl != NULL) { if (do_tree(tl->right())) return true; - if (do_list(tl)) return true; + if (this->do_list(tl)) return true; if (do_tree(tl->left())) return true; } return false; diff -r 429994fc0754 -r c5d4acbb943d src/share/vm/memory/metaspace.cpp --- a/src/share/vm/memory/metaspace.cpp Wed Nov 14 10:13:51 2012 -0800 +++ b/src/share/vm/memory/metaspace.cpp Thu Nov 15 14:29:28 2012 -0800 @@ -42,6 +42,10 @@ typedef BinaryTreeDictionary BlockTreeDictionary; typedef BinaryTreeDictionary ChunkTreeDictionary; +// Define this macro to enable slow integrity checking of +// the free chunk lists +const bool metaspace_slow_verify = false; + // Parameters for stress mode testing const uint metadata_deallocate_a_lot_block = 10; @@ -161,7 +165,17 @@ size_t sum_free_chunks_count(); void locked_verify_free_chunks_total(); + void slow_locked_verify_free_chunks_total() { + if (metaspace_slow_verify) { + locked_verify_free_chunks_total(); + } + } void locked_verify_free_chunks_count(); + void slow_locked_verify_free_chunks_count() { + if (metaspace_slow_verify) { + locked_verify_free_chunks_count(); + } + } void verify_free_chunks_count(); public: @@ -201,7 +215,17 @@ // Debug support void verify(); + void slow_verify() { + if (metaspace_slow_verify) { + verify(); + } + } void locked_verify(); + void slow_locked_verify() { + if (metaspace_slow_verify) { + locked_verify(); + } + } void verify_free_chunks_total(); void locked_print_free_chunks(outputStream* st); @@ -1507,7 +1531,7 @@ if (!UseConcMarkSweepGC && !SpaceManager::expand_lock()->is_locked()) { MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); - locked_verify_free_chunks_total(); + slow_locked_verify_free_chunks_total(); } #endif return _free_chunks_total; @@ -1524,10 +1548,10 @@ Mutex::_no_safepoint_check_flag); // This lock is only needed in debug because the verification // of the _free_chunks_totals walks the list of free chunks - locked_verify_free_chunks_count(); + slow_locked_verify_free_chunks_count(); } #endif - return _free_chunks_count; + return _free_chunks_count; } void ChunkManager::locked_verify_free_chunks_total() { @@ -1561,14 +1585,9 @@ } void ChunkManager::verify() { -#ifdef ASSERT - if (!UseConcMarkSweepGC) { - MutexLockerEx cl(SpaceManager::expand_lock(), - Mutex::_no_safepoint_check_flag); - locked_verify_free_chunks_total(); - locked_verify_free_chunks_count(); - } -#endif + MutexLockerEx cl(SpaceManager::expand_lock(), + Mutex::_no_safepoint_check_flag); + locked_verify(); } void ChunkManager::locked_verify() { @@ -1642,7 +1661,7 @@ free_list->set_head(chunk); // chunk is being returned to the chunk free list inc_free_chunks_total(chunk->capacity_word_size()); - locked_verify(); + slow_locked_verify(); } void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) { @@ -1650,8 +1669,8 @@ // manangement code for a Metaspace and does not hold the // lock. assert(chunk != NULL, "Deallocating NULL"); - // MutexLockerEx fcl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); - locked_verify(); + assert_lock_strong(SpaceManager::expand_lock()); + slow_locked_verify(); if (TraceMetadataChunkAllocation) { tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk " PTR_FORMAT " size " SIZE_FORMAT, @@ -1663,7 +1682,7 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) { assert_lock_strong(SpaceManager::expand_lock()); - locked_verify(); + slow_locked_verify(); Metachunk* chunk = NULL; if (!SpaceManager::is_humongous(word_size)) { @@ -1708,13 +1727,13 @@ #endif } } - locked_verify(); + slow_locked_verify(); return chunk; } Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { assert_lock_strong(SpaceManager::expand_lock()); - locked_verify(); + slow_locked_verify(); // Take from the beginning of the list Metachunk* chunk = free_chunks_get(word_size); @@ -1959,7 +1978,7 @@ ChunkManager* chunk_manager = vs_list()->chunk_manager(); - chunk_manager->locked_verify(); + chunk_manager->slow_locked_verify(); if (TraceMetadataChunkAllocation && Verbose) { gclog_or_tty->print_cr("~SpaceManager(): " PTR_FORMAT, this); @@ -2015,7 +2034,7 @@ humongous_chunks = next_humongous_chunks; } set_chunks_in_use(HumongousIndex, NULL); - chunk_manager->locked_verify(); + chunk_manager->slow_locked_verify(); } void SpaceManager::deallocate(MetaWord* p, size_t word_size) { @@ -2330,8 +2349,7 @@ ChunkManager* chunk = (mdtype == Metaspace::ClassType) ? Metaspace::class_space_list()->chunk_manager() : Metaspace::space_list()->chunk_manager(); - - chunk->verify_free_chunks_total(); + chunk->slow_verify(); return chunk->free_chunks_total(); } @@ -2435,6 +2453,11 @@ print_waste(out); } +void MetaspaceAux::verify_free_chunks() { + Metaspace::space_list()->chunk_manager()->verify(); + Metaspace::class_space_list()->chunk_manager()->verify(); +} + // Metaspace methods size_t Metaspace::_first_chunk_word_size = 0; diff -r 429994fc0754 -r c5d4acbb943d src/share/vm/memory/metaspace.hpp --- a/src/share/vm/memory/metaspace.hpp Wed Nov 14 10:13:51 2012 -0800 +++ b/src/share/vm/memory/metaspace.hpp Thu Nov 15 14:29:28 2012 -0800 @@ -189,6 +189,7 @@ static void print_waste(outputStream* out); static void dump(outputStream* out); + static void verify_free_chunks(); }; // Metaspace are deallocated when their class loader are GC'ed. diff -r 429994fc0754 -r c5d4acbb943d src/share/vm/memory/universe.cpp --- a/src/share/vm/memory/universe.cpp Wed Nov 14 10:13:51 2012 -0800 +++ b/src/share/vm/memory/universe.cpp Thu Nov 15 14:29:28 2012 -0800 @@ -1304,6 +1304,8 @@ if (!silent) gclog_or_tty->print("cldg "); ClassLoaderDataGraph::verify(); #endif + if (!silent) gclog_or_tty->print("metaspace chunks "); + MetaspaceAux::verify_free_chunks(); if (!silent) gclog_or_tty->print("hand "); JNIHandles::verify(); if (!silent) gclog_or_tty->print("C-heap ");