--- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp Wed Nov 14 10:13:51 2012 -0800
+++ b/hotspot/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<Chunk_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<Chunk_t, FreeList_t>* 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<Chunk_t, FreeList_t>* 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<Chunk_t, FreeList_t>* 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;
--- a/hotspot/src/share/vm/memory/metaspace.cpp Wed Nov 14 10:13:51 2012 -0800
+++ b/hotspot/src/share/vm/memory/metaspace.cpp Thu Nov 15 14:29:28 2012 -0800
@@ -42,6 +42,10 @@
typedef BinaryTreeDictionary<Metablock, FreeList> BlockTreeDictionary;
typedef BinaryTreeDictionary<Metachunk, FreeList> 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;
--- a/hotspot/src/share/vm/memory/metaspace.hpp Wed Nov 14 10:13:51 2012 -0800
+++ b/hotspot/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.
--- a/hotspot/src/share/vm/memory/universe.cpp Wed Nov 14 10:13:51 2012 -0800
+++ b/hotspot/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 ");