< prev index next >
src/hotspot/share/memory/metaspace.cpp
Print this page
*** 1259,1273 ****
// are assumed to be in chunks in use by the SpaceManager
// and all chunks in use by a SpaceManager are freed when
// the class loader using the SpaceManager is collected.
BlockFreelist* _block_freelists;
- // protects virtualspace and chunk expansions
- static const char* _expand_lock_name;
- static const int _expand_lock_rank;
- static Mutex* const _expand_lock;
-
private:
// Accessors
Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; }
void set_chunks_in_use(ChunkIndex index, Metachunk* v) {
_chunks_in_use[index] = v;
--- 1259,1268 ----
*** 1329,1340 ****
size_t allocated_chunks_bytes() const { return _allocated_chunks_words * BytesPerWord; }
size_t allocated_chunks_count() const { return _allocated_chunks_count; }
bool is_humongous(size_t word_size) { return word_size > medium_chunk_size(); }
- static Mutex* expand_lock() { return _expand_lock; }
-
// Increment the per Metaspace and global running sums for Metachunks
// by the given size. This is used when a Metachunk to added to
// the in-use list.
void inc_size_metrics(size_t words);
// Increment the per Metaspace and global running sums Metablocks by the given
--- 1324,1333 ----
*** 1414,1439 ****
};
uint const SpaceManager::_small_chunk_limit = 4;
uint const SpaceManager::_anon_and_delegating_metadata_specialize_chunk_limit = 4;
- const char* SpaceManager::_expand_lock_name =
- "SpaceManager chunk allocation lock";
- const int SpaceManager::_expand_lock_rank = Monitor::leaf - 1;
- Mutex* const SpaceManager::_expand_lock =
- new Mutex(SpaceManager::_expand_lock_rank,
- SpaceManager::_expand_lock_name,
- Mutex::_allow_vm_block_flag,
- Monitor::_safepoint_check_never);
-
void VirtualSpaceNode::inc_container_count() {
! assert_lock_strong(SpaceManager::expand_lock());
_container_count++;
}
void VirtualSpaceNode::dec_container_count() {
! assert_lock_strong(SpaceManager::expand_lock());
_container_count--;
}
#ifdef ASSERT
void VirtualSpaceNode::verify_container_count() {
--- 1407,1423 ----
};
uint const SpaceManager::_small_chunk_limit = 4;
uint const SpaceManager::_anon_and_delegating_metadata_specialize_chunk_limit = 4;
void VirtualSpaceNode::inc_container_count() {
! assert_lock_strong(MetaspaceExpand_lock);
_container_count++;
}
void VirtualSpaceNode::dec_container_count() {
! assert_lock_strong(MetaspaceExpand_lock);
_container_count--;
}
#ifdef ASSERT
void VirtualSpaceNode::verify_container_count() {
*** 1729,1739 ****
return result;
}
Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) {
! assert_lock_strong(SpaceManager::expand_lock());
Metachunk* result = take_from_committed(chunk_word_size);
return result;
}
bool VirtualSpaceNode::initialize() {
--- 1713,1723 ----
return result;
}
Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) {
! assert_lock_strong(MetaspaceExpand_lock);
Metachunk* result = take_from_committed(chunk_word_size);
return result;
}
bool VirtualSpaceNode::initialize() {
*** 1809,1851 ****
delete vsl;
}
}
void VirtualSpaceList::inc_reserved_words(size_t v) {
! assert_lock_strong(SpaceManager::expand_lock());
_reserved_words = _reserved_words + v;
}
void VirtualSpaceList::dec_reserved_words(size_t v) {
! assert_lock_strong(SpaceManager::expand_lock());
_reserved_words = _reserved_words - v;
}
#define assert_committed_below_limit() \
assert(MetaspaceUtils::committed_bytes() <= MaxMetaspaceSize, \
"Too much committed memory. Committed: " SIZE_FORMAT \
" limit (MaxMetaspaceSize): " SIZE_FORMAT, \
MetaspaceUtils::committed_bytes(), MaxMetaspaceSize);
void VirtualSpaceList::inc_committed_words(size_t v) {
! assert_lock_strong(SpaceManager::expand_lock());
_committed_words = _committed_words + v;
assert_committed_below_limit();
}
void VirtualSpaceList::dec_committed_words(size_t v) {
! assert_lock_strong(SpaceManager::expand_lock());
_committed_words = _committed_words - v;
assert_committed_below_limit();
}
void VirtualSpaceList::inc_virtual_space_count() {
! assert_lock_strong(SpaceManager::expand_lock());
_virtual_space_count++;
}
void VirtualSpaceList::dec_virtual_space_count() {
! assert_lock_strong(SpaceManager::expand_lock());
_virtual_space_count--;
}
void ChunkManager::remove_chunk(Metachunk* chunk) {
size_t word_size = chunk->word_size();
--- 1793,1835 ----
delete vsl;
}
}
void VirtualSpaceList::inc_reserved_words(size_t v) {
! assert_lock_strong(MetaspaceExpand_lock);
_reserved_words = _reserved_words + v;
}
void VirtualSpaceList::dec_reserved_words(size_t v) {
! assert_lock_strong(MetaspaceExpand_lock);
_reserved_words = _reserved_words - v;
}
#define assert_committed_below_limit() \
assert(MetaspaceUtils::committed_bytes() <= MaxMetaspaceSize, \
"Too much committed memory. Committed: " SIZE_FORMAT \
" limit (MaxMetaspaceSize): " SIZE_FORMAT, \
MetaspaceUtils::committed_bytes(), MaxMetaspaceSize);
void VirtualSpaceList::inc_committed_words(size_t v) {
! assert_lock_strong(MetaspaceExpand_lock);
_committed_words = _committed_words + v;
assert_committed_below_limit();
}
void VirtualSpaceList::dec_committed_words(size_t v) {
! assert_lock_strong(MetaspaceExpand_lock);
_committed_words = _committed_words - v;
assert_committed_below_limit();
}
void VirtualSpaceList::inc_virtual_space_count() {
! assert_lock_strong(MetaspaceExpand_lock);
_virtual_space_count++;
}
void VirtualSpaceList::dec_virtual_space_count() {
! assert_lock_strong(MetaspaceExpand_lock);
_virtual_space_count--;
}
void ChunkManager::remove_chunk(Metachunk* chunk) {
size_t word_size = chunk->word_size();
*** 1859,1869 ****
// Chunk has been removed from the chunks free list, update counters.
account_for_removed_chunk(chunk);
}
bool ChunkManager::attempt_to_coalesce_around_chunk(Metachunk* chunk, ChunkIndex target_chunk_type) {
! assert_lock_strong(SpaceManager::expand_lock());
assert(chunk != NULL, "invalid chunk pointer");
// Check for valid merge combinations.
assert((chunk->get_chunk_type() == SpecializedIndex &&
(target_chunk_type == SmallIndex || target_chunk_type == MediumIndex)) ||
(chunk->get_chunk_type() == SmallIndex && target_chunk_type == MediumIndex),
--- 1843,1853 ----
// Chunk has been removed from the chunks free list, update counters.
account_for_removed_chunk(chunk);
}
bool ChunkManager::attempt_to_coalesce_around_chunk(Metachunk* chunk, ChunkIndex target_chunk_type) {
! assert_lock_strong(MetaspaceExpand_lock);
assert(chunk != NULL, "invalid chunk pointer");
// Check for valid merge combinations.
assert((chunk->get_chunk_type() == SpecializedIndex &&
(target_chunk_type == SmallIndex || target_chunk_type == MediumIndex)) ||
(chunk->get_chunk_type() == SmallIndex && target_chunk_type == MediumIndex),
*** 1992,2002 ****
// Walk the list of VirtualSpaceNodes and delete
// nodes with a 0 container_count. Remove Metachunks in
// the node from their respective freelists.
void VirtualSpaceList::purge(ChunkManager* chunk_manager) {
assert(SafepointSynchronize::is_at_safepoint(), "must be called at safepoint for contains to work");
! assert_lock_strong(SpaceManager::expand_lock());
// Don't use a VirtualSpaceListIterator because this
// list is being changed and a straightforward use of an iterator is not safe.
VirtualSpaceNode* purged_vsl = NULL;
VirtualSpaceNode* prev_vsl = virtual_space_list();
VirtualSpaceNode* next_vsl = prev_vsl;
--- 1976,1986 ----
// Walk the list of VirtualSpaceNodes and delete
// nodes with a 0 container_count. Remove Metachunks in
// the node from their respective freelists.
void VirtualSpaceList::purge(ChunkManager* chunk_manager) {
assert(SafepointSynchronize::is_at_safepoint(), "must be called at safepoint for contains to work");
! assert_lock_strong(MetaspaceExpand_lock);
// Don't use a VirtualSpaceListIterator because this
// list is being changed and a straightforward use of an iterator is not safe.
VirtualSpaceNode* purged_vsl = NULL;
VirtualSpaceNode* prev_vsl = virtual_space_list();
VirtualSpaceNode* next_vsl = prev_vsl;
*** 2056,2066 ****
}
return false;
}
void VirtualSpaceList::retire_current_virtual_space() {
! assert_lock_strong(SpaceManager::expand_lock());
VirtualSpaceNode* vsn = current_virtual_space();
ChunkManager* cm = is_class() ? Metaspace::chunk_manager_class() :
Metaspace::chunk_manager_metadata();
--- 2040,2050 ----
}
return false;
}
void VirtualSpaceList::retire_current_virtual_space() {
! assert_lock_strong(MetaspaceExpand_lock);
VirtualSpaceNode* vsn = current_virtual_space();
ChunkManager* cm = is_class() ? Metaspace::chunk_manager_class() :
Metaspace::chunk_manager_metadata();
*** 2098,2108 ****
_virtual_space_list(NULL),
_current_virtual_space(NULL),
_reserved_words(0),
_committed_words(0),
_virtual_space_count(0) {
! MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
create_new_virtual_space(word_size);
}
VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
--- 2082,2092 ----
_virtual_space_list(NULL),
_current_virtual_space(NULL),
_reserved_words(0),
_committed_words(0),
_virtual_space_count(0) {
! MutexLockerEx cl(MetaspaceExpand_lock,
Mutex::_no_safepoint_check_flag);
create_new_virtual_space(word_size);
}
VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
*** 2110,2120 ****
_virtual_space_list(NULL),
_current_virtual_space(NULL),
_reserved_words(0),
_committed_words(0),
_virtual_space_count(0) {
! MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
VirtualSpaceNode* class_entry = new VirtualSpaceNode(is_class(), rs);
bool succeeded = class_entry->initialize();
if (succeeded) {
link_vs(class_entry);
--- 2094,2104 ----
_virtual_space_list(NULL),
_current_virtual_space(NULL),
_reserved_words(0),
_committed_words(0),
_virtual_space_count(0) {
! MutexLockerEx cl(MetaspaceExpand_lock,
Mutex::_no_safepoint_check_flag);
VirtualSpaceNode* class_entry = new VirtualSpaceNode(is_class(), rs);
bool succeeded = class_entry->initialize();
if (succeeded) {
link_vs(class_entry);
*** 2125,2135 ****
return current_virtual_space()->free_words_in_vs() * BytesPerWord;
}
// Allocate another meta virtual space and add it to the list.
bool VirtualSpaceList::create_new_virtual_space(size_t vs_word_size) {
! assert_lock_strong(SpaceManager::expand_lock());
if (is_class()) {
assert(false, "We currently don't support more than one VirtualSpace for"
" the compressed class space. The initialization of the"
" CCS uses another code path and should not hit this path.");
--- 2109,2119 ----
return current_virtual_space()->free_words_in_vs() * BytesPerWord;
}
// Allocate another meta virtual space and add it to the list.
bool VirtualSpaceList::create_new_virtual_space(size_t vs_word_size) {
! assert_lock_strong(MetaspaceExpand_lock);
if (is_class()) {
assert(false, "We currently don't support more than one VirtualSpace for"
" the compressed class space. The initialization of the"
" CCS uses another code path and should not hit this path.");
*** 2614,2631 ****
return free_chunks_total_words() * BytesPerWord;
}
// Update internal accounting after a chunk was added
void ChunkManager::account_for_added_chunk(const Metachunk* c) {
! assert_lock_strong(SpaceManager::expand_lock());
_free_chunks_count ++;
_free_chunks_total += c->word_size();
}
// Update internal accounting after a chunk was removed
void ChunkManager::account_for_removed_chunk(const Metachunk* c) {
! assert_lock_strong(SpaceManager::expand_lock());
assert(_free_chunks_count >= 1,
"ChunkManager::_free_chunks_count: about to go negative (" SIZE_FORMAT ").", _free_chunks_count);
assert(_free_chunks_total >= c->word_size(),
"ChunkManager::_free_chunks_total: about to go negative"
"(now: " SIZE_FORMAT ", decrement value: " SIZE_FORMAT ").", _free_chunks_total, c->word_size());
--- 2598,2615 ----
return free_chunks_total_words() * BytesPerWord;
}
// Update internal accounting after a chunk was added
void ChunkManager::account_for_added_chunk(const Metachunk* c) {
! assert_lock_strong(MetaspaceExpand_lock);
_free_chunks_count ++;
_free_chunks_total += c->word_size();
}
// Update internal accounting after a chunk was removed
void ChunkManager::account_for_removed_chunk(const Metachunk* c) {
! assert_lock_strong(MetaspaceExpand_lock);
assert(_free_chunks_count >= 1,
"ChunkManager::_free_chunks_count: about to go negative (" SIZE_FORMAT ").", _free_chunks_count);
assert(_free_chunks_total >= c->word_size(),
"ChunkManager::_free_chunks_total: about to go negative"
"(now: " SIZE_FORMAT ", decrement value: " SIZE_FORMAT ").", _free_chunks_total, c->word_size());
*** 2633,2644 ****
_free_chunks_total -= c->word_size();
}
size_t ChunkManager::free_chunks_count() {
#ifdef ASSERT
! if (!UseConcMarkSweepGC && !SpaceManager::expand_lock()->is_locked()) {
! MutexLockerEx cl(SpaceManager::expand_lock(),
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
slow_locked_verify_free_chunks_count();
}
--- 2617,2628 ----
_free_chunks_total -= c->word_size();
}
size_t ChunkManager::free_chunks_count() {
#ifdef ASSERT
! if (!UseConcMarkSweepGC && !MetaspaceExpand_lock->is_locked()) {
! MutexLockerEx cl(MetaspaceExpand_lock,
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
slow_locked_verify_free_chunks_count();
}
*** 2655,2695 ****
assert(index != HumongousIndex, "Do not call for humongous chunks.");
return get_size_for_nonhumongous_chunktype(index, is_class());
}
void ChunkManager::locked_verify_free_chunks_total() {
! assert_lock_strong(SpaceManager::expand_lock());
assert(sum_free_chunks() == _free_chunks_total,
"_free_chunks_total " SIZE_FORMAT " is not the"
" same as sum " SIZE_FORMAT, _free_chunks_total,
sum_free_chunks());
}
void ChunkManager::verify_free_chunks_total() {
! MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
locked_verify_free_chunks_total();
}
void ChunkManager::locked_verify_free_chunks_count() {
! assert_lock_strong(SpaceManager::expand_lock());
assert(sum_free_chunks_count() == _free_chunks_count,
"_free_chunks_count " SIZE_FORMAT " is not the"
" same as sum " SIZE_FORMAT, _free_chunks_count,
sum_free_chunks_count());
}
void ChunkManager::verify_free_chunks_count() {
#ifdef ASSERT
! MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
locked_verify_free_chunks_count();
#endif
}
void ChunkManager::verify() {
! MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
locked_verify();
}
void ChunkManager::locked_verify() {
--- 2639,2679 ----
assert(index != HumongousIndex, "Do not call for humongous chunks.");
return get_size_for_nonhumongous_chunktype(index, is_class());
}
void ChunkManager::locked_verify_free_chunks_total() {
! assert_lock_strong(MetaspaceExpand_lock);
assert(sum_free_chunks() == _free_chunks_total,
"_free_chunks_total " SIZE_FORMAT " is not the"
" same as sum " SIZE_FORMAT, _free_chunks_total,
sum_free_chunks());
}
void ChunkManager::verify_free_chunks_total() {
! MutexLockerEx cl(MetaspaceExpand_lock,
Mutex::_no_safepoint_check_flag);
locked_verify_free_chunks_total();
}
void ChunkManager::locked_verify_free_chunks_count() {
! assert_lock_strong(MetaspaceExpand_lock);
assert(sum_free_chunks_count() == _free_chunks_count,
"_free_chunks_count " SIZE_FORMAT " is not the"
" same as sum " SIZE_FORMAT, _free_chunks_count,
sum_free_chunks_count());
}
void ChunkManager::verify_free_chunks_count() {
#ifdef ASSERT
! MutexLockerEx cl(MetaspaceExpand_lock,
Mutex::_no_safepoint_check_flag);
locked_verify_free_chunks_count();
#endif
}
void ChunkManager::verify() {
! MutexLockerEx cl(MetaspaceExpand_lock,
Mutex::_no_safepoint_check_flag);
locked_verify();
}
void ChunkManager::locked_verify() {
*** 2707,2723 ****
}
}
}
void ChunkManager::locked_print_free_chunks(outputStream* st) {
! assert_lock_strong(SpaceManager::expand_lock());
st->print_cr("Free chunk total " SIZE_FORMAT " count " SIZE_FORMAT,
_free_chunks_total, _free_chunks_count);
}
void ChunkManager::locked_print_sum_free_chunks(outputStream* st) {
! assert_lock_strong(SpaceManager::expand_lock());
st->print_cr("Sum free chunk total " SIZE_FORMAT " count " SIZE_FORMAT,
sum_free_chunks(), sum_free_chunks_count());
}
ChunkList* ChunkManager::free_chunks(ChunkIndex index) {
--- 2691,2707 ----
}
}
}
void ChunkManager::locked_print_free_chunks(outputStream* st) {
! assert_lock_strong(MetaspaceExpand_lock);
st->print_cr("Free chunk total " SIZE_FORMAT " count " SIZE_FORMAT,
_free_chunks_total, _free_chunks_count);
}
void ChunkManager::locked_print_sum_free_chunks(outputStream* st) {
! assert_lock_strong(MetaspaceExpand_lock);
st->print_cr("Sum free chunk total " SIZE_FORMAT " count " SIZE_FORMAT,
sum_free_chunks(), sum_free_chunks_count());
}
ChunkList* ChunkManager::free_chunks(ChunkIndex index) {
*** 2728,2738 ****
}
// These methods that sum the free chunk lists are used in printing
// methods that are used in product builds.
size_t ChunkManager::sum_free_chunks() {
! assert_lock_strong(SpaceManager::expand_lock());
size_t result = 0;
for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
ChunkList* list = free_chunks(i);
if (list == NULL) {
--- 2712,2722 ----
}
// These methods that sum the free chunk lists are used in printing
// methods that are used in product builds.
size_t ChunkManager::sum_free_chunks() {
! assert_lock_strong(MetaspaceExpand_lock);
size_t result = 0;
for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
ChunkList* list = free_chunks(i);
if (list == NULL) {
*** 2744,2754 ****
result = result + humongous_dictionary()->total_size();
return result;
}
size_t ChunkManager::sum_free_chunks_count() {
! assert_lock_strong(SpaceManager::expand_lock());
size_t count = 0;
for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
ChunkList* list = free_chunks(i);
if (list == NULL) {
continue;
--- 2728,2738 ----
result = result + humongous_dictionary()->total_size();
return result;
}
size_t ChunkManager::sum_free_chunks_count() {
! assert_lock_strong(MetaspaceExpand_lock);
size_t count = 0;
for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
ChunkList* list = free_chunks(i);
if (list == NULL) {
continue;
*** 2860,2870 ****
return target_chunk;
}
Metachunk* ChunkManager::free_chunks_get(size_t word_size) {
! assert_lock_strong(SpaceManager::expand_lock());
slow_locked_verify();
Metachunk* chunk = NULL;
bool we_did_split_a_chunk = false;
--- 2844,2854 ----
return target_chunk;
}
Metachunk* ChunkManager::free_chunks_get(size_t word_size) {
! assert_lock_strong(MetaspaceExpand_lock);
slow_locked_verify();
Metachunk* chunk = NULL;
bool we_did_split_a_chunk = false;
*** 2967,2977 ****
return chunk;
}
Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) {
! assert_lock_strong(SpaceManager::expand_lock());
slow_locked_verify();
// Take from the beginning of the list
Metachunk* chunk = free_chunks_get(word_size);
if (chunk == NULL) {
--- 2951,2961 ----
return chunk;
}
Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) {
! assert_lock_strong(MetaspaceExpand_lock);
slow_locked_verify();
// Take from the beginning of the list
Metachunk* chunk = free_chunks_get(word_size);
if (chunk == NULL) {
*** 2999,3009 ****
return chunk;
}
void ChunkManager::return_single_chunk(ChunkIndex index, Metachunk* chunk) {
! assert_lock_strong(SpaceManager::expand_lock());
DEBUG_ONLY(do_verify_chunk(chunk);)
assert(chunk->get_chunk_type() == index, "Chunk does not match expected index.");
assert(chunk != NULL, "Expected chunk.");
assert(chunk->container() != NULL, "Container should have been set.");
assert(chunk->is_tagged_free() == false, "Chunk should be in use.");
--- 2983,2993 ----
return chunk;
}
void ChunkManager::return_single_chunk(ChunkIndex index, Metachunk* chunk) {
! assert_lock_strong(MetaspaceExpand_lock);
DEBUG_ONLY(do_verify_chunk(chunk);)
assert(chunk->get_chunk_type() == index, "Chunk does not match expected index.");
assert(chunk != NULL, "Expected chunk.");
assert(chunk->container() != NULL, "Container should have been set.");
assert(chunk->is_tagged_free() == false, "Chunk should be in use.");
*** 3088,3109 ****
void ChunkManager::print_on(outputStream* out) const {
_humongous_dictionary.report_statistics(out);
}
void ChunkManager::locked_get_statistics(ChunkManagerStatistics* stat) const {
! assert_lock_strong(SpaceManager::expand_lock());
for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
stat->num_by_type[i] = num_free_chunks(i);
stat->single_size_by_type[i] = size_by_index(i);
stat->total_size_by_type[i] = size_free_chunks_in_bytes(i);
}
stat->num_humongous_chunks = num_free_chunks(HumongousIndex);
stat->total_size_humongous_chunks = size_free_chunks_in_bytes(HumongousIndex);
}
void ChunkManager::get_statistics(ChunkManagerStatistics* stat) const {
! MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
locked_get_statistics(stat);
}
void ChunkManager::print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale) {
--- 3072,3093 ----
void ChunkManager::print_on(outputStream* out) const {
_humongous_dictionary.report_statistics(out);
}
void ChunkManager::locked_get_statistics(ChunkManagerStatistics* stat) const {
! assert_lock_strong(MetaspaceExpand_lock);
for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
stat->num_by_type[i] = num_free_chunks(i);
stat->single_size_by_type[i] = size_by_index(i);
stat->total_size_by_type[i] = size_free_chunks_in_bytes(i);
}
stat->num_humongous_chunks = num_free_chunks(HumongousIndex);
stat->total_size_humongous_chunks = size_free_chunks_in_bytes(HumongousIndex);
}
void ChunkManager::get_statistics(ChunkManagerStatistics* stat) const {
! MutexLockerEx cl(MetaspaceExpand_lock,
Mutex::_no_safepoint_check_flag);
locked_get_statistics(stat);
}
void ChunkManager::print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale) {
*** 3398,3408 ****
assert(vs_list()->current_virtual_space() != NULL,
"Should have been set");
assert(current_chunk() == NULL ||
current_chunk()->allocate(word_size) == NULL,
"Don't need to expand");
! MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
if (log_is_enabled(Trace, gc, metaspace, freelist)) {
size_t words_left = 0;
size_t words_used = 0;
if (current_chunk() != NULL) {
--- 3382,3392 ----
assert(vs_list()->current_virtual_space() != NULL,
"Should have been set");
assert(current_chunk() == NULL ||
current_chunk()->allocate(word_size) == NULL,
"Don't need to expand");
! MutexLockerEx cl(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
if (log_is_enabled(Trace, gc, metaspace, freelist)) {
size_t words_left = 0;
size_t words_used = 0;
if (current_chunk() != NULL) {
*** 3467,3477 ****
{
initialize();
}
void SpaceManager::inc_size_metrics(size_t words) {
! assert_lock_strong(SpaceManager::expand_lock());
// Total of allocated Metachunks and allocated Metachunks count
// for each SpaceManager
_allocated_chunks_words = _allocated_chunks_words + words;
_allocated_chunks_count++;
// Global total of capacity in allocated Metachunks
--- 3451,3461 ----
{
initialize();
}
void SpaceManager::inc_size_metrics(size_t words) {
! assert_lock_strong(MetaspaceExpand_lock);
// Total of allocated Metachunks and allocated Metachunks count
// for each SpaceManager
_allocated_chunks_words = _allocated_chunks_words + words;
_allocated_chunks_count++;
// Global total of capacity in allocated Metachunks
*** 3506,3522 ****
_current_chunk = NULL;
log_trace(gc, metaspace, freelist)("SpaceManager(): " PTR_FORMAT, p2i(this));
}
SpaceManager::~SpaceManager() {
! // This call this->_lock which can't be done while holding expand_lock()
assert(sum_capacity_in_chunks_in_use() == allocated_chunks_words(),
"sum_capacity_in_chunks_in_use() " SIZE_FORMAT
" allocated_chunks_words() " SIZE_FORMAT,
sum_capacity_in_chunks_in_use(), allocated_chunks_words());
! MutexLockerEx fcl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
assert(sum_count_in_chunks_in_use() == allocated_chunks_count(),
"sum_count_in_chunks_in_use() " SIZE_FORMAT
" allocated_chunks_count() " SIZE_FORMAT,
--- 3490,3506 ----
_current_chunk = NULL;
log_trace(gc, metaspace, freelist)("SpaceManager(): " PTR_FORMAT, p2i(this));
}
SpaceManager::~SpaceManager() {
! // This call this->_lock which can't be done while holding MetaspaceExpand_lock
assert(sum_capacity_in_chunks_in_use() == allocated_chunks_words(),
"sum_capacity_in_chunks_in_use() " SIZE_FORMAT
" allocated_chunks_words() " SIZE_FORMAT,
sum_capacity_in_chunks_in_use(), allocated_chunks_words());
! MutexLockerEx fcl(MetaspaceExpand_lock,
Mutex::_no_safepoint_check_flag);
assert(sum_count_in_chunks_in_use() == allocated_chunks_count(),
"sum_count_in_chunks_in_use() " SIZE_FORMAT
" allocated_chunks_count() " SIZE_FORMAT,
*** 3777,3807 ****
size_t MetaspaceUtils::free_bytes() {
return free_bytes(Metaspace::ClassType) + free_bytes(Metaspace::NonClassType);
}
void MetaspaceUtils::dec_capacity(Metaspace::MetadataType mdtype, size_t words) {
! assert_lock_strong(SpaceManager::expand_lock());
assert(words <= capacity_words(mdtype),
"About to decrement below 0: words " SIZE_FORMAT
" is greater than _capacity_words[%u] " SIZE_FORMAT,
words, mdtype, capacity_words(mdtype));
_capacity_words[mdtype] -= words;
}
void MetaspaceUtils::inc_capacity(Metaspace::MetadataType mdtype, size_t words) {
! assert_lock_strong(SpaceManager::expand_lock());
// Needs to be atomic
_capacity_words[mdtype] += words;
}
void MetaspaceUtils::dec_used(Metaspace::MetadataType mdtype, size_t words) {
assert(words <= used_words(mdtype),
"About to decrement below 0: words " SIZE_FORMAT
" is greater than _used_words[%u] " SIZE_FORMAT,
words, mdtype, used_words(mdtype));
// For CMS deallocation of the Metaspaces occurs during the
! // sweep which is a concurrent phase. Protection by the expand_lock()
// is not enough since allocation is on a per Metaspace basis
// and protected by the Metaspace lock.
Atomic::sub(words, &_used_words[mdtype]);
}
--- 3761,3791 ----
size_t MetaspaceUtils::free_bytes() {
return free_bytes(Metaspace::ClassType) + free_bytes(Metaspace::NonClassType);
}
void MetaspaceUtils::dec_capacity(Metaspace::MetadataType mdtype, size_t words) {
! assert_lock_strong(MetaspaceExpand_lock);
assert(words <= capacity_words(mdtype),
"About to decrement below 0: words " SIZE_FORMAT
" is greater than _capacity_words[%u] " SIZE_FORMAT,
words, mdtype, capacity_words(mdtype));
_capacity_words[mdtype] -= words;
}
void MetaspaceUtils::inc_capacity(Metaspace::MetadataType mdtype, size_t words) {
! assert_lock_strong(MetaspaceExpand_lock);
// Needs to be atomic
_capacity_words[mdtype] += words;
}
void MetaspaceUtils::dec_used(Metaspace::MetadataType mdtype, size_t words) {
assert(words <= used_words(mdtype),
"About to decrement below 0: words " SIZE_FORMAT
" is greater than _used_words[%u] " SIZE_FORMAT,
words, mdtype, used_words(mdtype));
// For CMS deallocation of the Metaspaces occurs during the
! // sweep which is a concurrent phase. Protection by the MetaspaceExpand_lock
// is not enough since allocation is on a per Metaspace basis
// and protected by the Metaspace lock.
Atomic::sub(words, &_used_words[mdtype]);
}
*** 4226,4236 ****
print_waste(out);
}
// Prints an ASCII representation of the given space.
void MetaspaceUtils::print_metaspace_map(outputStream* out, Metaspace::MetadataType mdtype) {
! MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
const bool for_class = mdtype == Metaspace::ClassType ? true : false;
VirtualSpaceList* const vsl = for_class ? Metaspace::class_space_list() : Metaspace::space_list();
if (vsl != NULL) {
if (for_class) {
if (!Metaspace::using_class_space()) {
--- 4210,4220 ----
print_waste(out);
}
// Prints an ASCII representation of the given space.
void MetaspaceUtils::print_metaspace_map(outputStream* out, Metaspace::MetadataType mdtype) {
! MutexLockerEx cl(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
const bool for_class = mdtype == Metaspace::ClassType ? true : false;
VirtualSpaceList* const vsl = for_class ? Metaspace::class_space_list() : Metaspace::space_list();
if (vsl != NULL) {
if (for_class) {
if (!Metaspace::using_class_space()) {
*** 4773,4783 ****
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);
}
--- 4757,4767 ----
void Metaspace::purge(MetadataType mdtype) {
get_space_list(mdtype)->purge(get_chunk_manager(mdtype));
}
void Metaspace::purge() {
! MutexLockerEx cl(MetaspaceExpand_lock,
Mutex::_no_safepoint_check_flag);
purge(NonClassType);
if (using_class_space()) {
purge(ClassType);
}
*** 4841,4851 ****
if (Metaspace::using_class_space()) {
// Allocate SpaceManager for classes.
_class_vsm = new SpaceManager(Metaspace::ClassType, type, lock);
}
! MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
// Allocate chunk for metadata objects
initialize_first_chunk(type, Metaspace::NonClassType);
// Allocate chunk for class metadata objects
--- 4825,4835 ----
if (Metaspace::using_class_space()) {
// Allocate SpaceManager for classes.
_class_vsm = new SpaceManager(Metaspace::ClassType, type, lock);
}
! MutexLockerEx cl(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
// Allocate chunk for metadata objects
initialize_first_chunk(type, Metaspace::NonClassType);
// Allocate chunk for class metadata objects
*** 5048,5058 ****
}
}
static void test_virtual_space_list_large_chunk() {
VirtualSpaceList* vs_list = new VirtualSpaceList(os::vm_allocation_granularity());
! MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
// A size larger than VirtualSpaceSize (256k) and add one page to make it _not_ be
// vm_allocation_granularity aligned on Windows.
size_t large_size = (size_t)(2*256*K + (os::vm_page_size()/BytesPerWord));
large_size += (os::vm_page_size()/BytesPerWord);
vs_list->get_new_chunk(large_size, 0);
--- 5032,5042 ----
}
}
static void test_virtual_space_list_large_chunk() {
VirtualSpaceList* vs_list = new VirtualSpaceList(os::vm_allocation_granularity());
! MutexLockerEx cl(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
// A size larger than VirtualSpaceSize (256k) and add one page to make it _not_ be
// vm_allocation_granularity aligned on Windows.
size_t large_size = (size_t)(2*256*K + (os::vm_page_size()/BytesPerWord));
large_size += (os::vm_page_size()/BytesPerWord);
vs_list->get_new_chunk(large_size, 0);
*** 5083,5093 ****
assert(words_left % SpecializedChunk == 0, "should be nothing left");
}
public:
static void test() {
! MutexLockerEx ml(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
const size_t vsn_test_size_words = MediumChunk * 4;
const size_t vsn_test_size_bytes = vsn_test_size_words * BytesPerWord;
// The chunk sizes must be multiples of eachother, or this will fail
STATIC_ASSERT(MediumChunk % SmallChunk == 0);
--- 5067,5077 ----
assert(words_left % SpecializedChunk == 0, "should be nothing left");
}
public:
static void test() {
! MutexLockerEx ml(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
const size_t vsn_test_size_words = MediumChunk * 4;
const size_t vsn_test_size_bytes = vsn_test_size_words * BytesPerWord;
// The chunk sizes must be multiples of eachother, or this will fail
STATIC_ASSERT(MediumChunk % SmallChunk == 0);
< prev index next >