1.1 --- a/src/share/vm/memory/metaspace.cpp Mon May 20 10:44:33 2013 -0700 1.2 +++ b/src/share/vm/memory/metaspace.cpp Mon May 20 22:34:24 2013 -0700 1.3 @@ -562,6 +562,9 @@ 1.4 // protects allocations and contains. 1.5 Mutex* const _lock; 1.6 1.7 + // Type of metadata allocated. 1.8 + Metaspace::MetadataType _mdtype; 1.9 + 1.10 // Chunk related size 1.11 size_t _medium_chunk_bunch; 1.12 1.13 @@ -606,6 +609,7 @@ 1.14 return (BlockFreelist*) &_block_freelists; 1.15 } 1.16 1.17 + Metaspace::MetadataType mdtype() { return _mdtype; } 1.18 VirtualSpaceList* vs_list() const { return _vs_list; } 1.19 1.20 Metachunk* current_chunk() const { return _current_chunk; } 1.21 @@ -626,7 +630,8 @@ 1.22 void initialize(); 1.23 1.24 public: 1.25 - SpaceManager(Mutex* lock, 1.26 + SpaceManager(Metaspace::MetadataType mdtype, 1.27 + Mutex* lock, 1.28 VirtualSpaceList* vs_list); 1.29 ~SpaceManager(); 1.30 1.31 @@ -2032,9 +2037,11 @@ 1.32 } 1.33 } 1.34 1.35 -SpaceManager::SpaceManager(Mutex* lock, 1.36 +SpaceManager::SpaceManager(Metaspace::MetadataType mdtype, 1.37 + Mutex* lock, 1.38 VirtualSpaceList* vs_list) : 1.39 _vs_list(vs_list), 1.40 + _mdtype(mdtype), 1.41 _allocated_blocks_words(0), 1.42 _allocated_chunks_words(0), 1.43 _allocated_chunks_count(0), 1.44 @@ -2050,27 +2057,27 @@ 1.45 _allocated_chunks_words = _allocated_chunks_words + words; 1.46 _allocated_chunks_count++; 1.47 // Global total of capacity in allocated Metachunks 1.48 - MetaspaceAux::inc_capacity(words); 1.49 + MetaspaceAux::inc_capacity(mdtype(), words); 1.50 // Global total of allocated Metablocks. 1.51 // used_words_slow() includes the overhead in each 1.52 // Metachunk so include it in the used when the 1.53 // Metachunk is first added (so only added once per 1.54 // Metachunk). 1.55 - MetaspaceAux::inc_used(Metachunk::overhead()); 1.56 + MetaspaceAux::inc_used(mdtype(), Metachunk::overhead()); 1.57 } 1.58 1.59 void SpaceManager::inc_used_metrics(size_t words) { 1.60 // Add to the per SpaceManager total 1.61 Atomic::add_ptr(words, &_allocated_blocks_words); 1.62 // Add to the global total 1.63 - MetaspaceAux::inc_used(words); 1.64 + MetaspaceAux::inc_used(mdtype(), words); 1.65 } 1.66 1.67 void SpaceManager::dec_total_from_size_metrics() { 1.68 - MetaspaceAux::dec_capacity(allocated_chunks_words()); 1.69 - MetaspaceAux::dec_used(allocated_blocks_words()); 1.70 + MetaspaceAux::dec_capacity(mdtype(), allocated_chunks_words()); 1.71 + MetaspaceAux::dec_used(mdtype(), allocated_blocks_words()); 1.72 // Also deduct the overhead per Metachunk 1.73 - MetaspaceAux::dec_used(allocated_chunks_count() * Metachunk::overhead()); 1.74 + MetaspaceAux::dec_used(mdtype(), allocated_chunks_count() * Metachunk::overhead()); 1.75 } 1.76 1.77 void SpaceManager::initialize() { 1.78 @@ -2470,8 +2477,8 @@ 1.79 // MetaspaceAux 1.80 1.81 1.82 -size_t MetaspaceAux::_allocated_capacity_words = 0; 1.83 -size_t MetaspaceAux::_allocated_used_words = 0; 1.84 +size_t MetaspaceAux::_allocated_capacity_words[] = {0, 0}; 1.85 +size_t MetaspaceAux::_allocated_used_words[] = {0, 0}; 1.86 1.87 size_t MetaspaceAux::free_bytes() { 1.88 size_t result = 0; 1.89 @@ -2484,40 +2491,40 @@ 1.90 return result; 1.91 } 1.92 1.93 -void MetaspaceAux::dec_capacity(size_t words) { 1.94 +void MetaspaceAux::dec_capacity(Metaspace::MetadataType mdtype, size_t words) { 1.95 assert_lock_strong(SpaceManager::expand_lock()); 1.96 - assert(words <= _allocated_capacity_words, 1.97 + assert(words <= allocated_capacity_words(mdtype), 1.98 err_msg("About to decrement below 0: words " SIZE_FORMAT 1.99 - " is greater than _allocated_capacity_words " SIZE_FORMAT, 1.100 - words, _allocated_capacity_words)); 1.101 - _allocated_capacity_words = _allocated_capacity_words - words; 1.102 + " is greater than _allocated_capacity_words[%u] " SIZE_FORMAT, 1.103 + words, mdtype, allocated_capacity_words(mdtype))); 1.104 + _allocated_capacity_words[mdtype] -= words; 1.105 } 1.106 1.107 -void MetaspaceAux::inc_capacity(size_t words) { 1.108 +void MetaspaceAux::inc_capacity(Metaspace::MetadataType mdtype, size_t words) { 1.109 assert_lock_strong(SpaceManager::expand_lock()); 1.110 // Needs to be atomic 1.111 - _allocated_capacity_words = _allocated_capacity_words + words; 1.112 + _allocated_capacity_words[mdtype] += words; 1.113 } 1.114 1.115 -void MetaspaceAux::dec_used(size_t words) { 1.116 - assert(words <= _allocated_used_words, 1.117 +void MetaspaceAux::dec_used(Metaspace::MetadataType mdtype, size_t words) { 1.118 + assert(words <= allocated_used_words(mdtype), 1.119 err_msg("About to decrement below 0: words " SIZE_FORMAT 1.120 - " is greater than _allocated_used_words " SIZE_FORMAT, 1.121 - words, _allocated_used_words)); 1.122 + " is greater than _allocated_used_words[%u] " SIZE_FORMAT, 1.123 + words, mdtype, allocated_used_words(mdtype))); 1.124 // For CMS deallocation of the Metaspaces occurs during the 1.125 // sweep which is a concurrent phase. Protection by the expand_lock() 1.126 // is not enough since allocation is on a per Metaspace basis 1.127 // and protected by the Metaspace lock. 1.128 jlong minus_words = (jlong) - (jlong) words; 1.129 - Atomic::add_ptr(minus_words, &_allocated_used_words); 1.130 + Atomic::add_ptr(minus_words, &_allocated_used_words[mdtype]); 1.131 } 1.132 1.133 -void MetaspaceAux::inc_used(size_t words) { 1.134 +void MetaspaceAux::inc_used(Metaspace::MetadataType mdtype, size_t words) { 1.135 // _allocated_used_words tracks allocations for 1.136 // each piece of metadata. Those allocations are 1.137 // generally done concurrently by different application 1.138 // threads so must be done atomically. 1.139 - Atomic::add_ptr(words, &_allocated_used_words); 1.140 + Atomic::add_ptr(words, &_allocated_used_words[mdtype]); 1.141 } 1.142 1.143 size_t MetaspaceAux::used_bytes_slow(Metaspace::MetadataType mdtype) { 1.144 @@ -2619,21 +2626,19 @@ 1.145 SIZE_FORMAT "K, used " SIZE_FORMAT "K," 1.146 " reserved " SIZE_FORMAT "K", 1.147 allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_in_bytes()/K); 1.148 -#if 0 1.149 -// The calls to capacity_bytes_slow() and used_bytes_slow() cause 1.150 -// lock ordering assertion failures with some collectors. Do 1.151 -// not include this code until the lock ordering is fixed. 1.152 - if (PrintGCDetails && Verbose) { 1.153 - out->print_cr(" data space " 1.154 - SIZE_FORMAT "K, used " SIZE_FORMAT "K," 1.155 - " reserved " SIZE_FORMAT "K", 1.156 - capacity_bytes_slow(nct)/K, used_bytes_slow(nct)/K, reserved_in_bytes(nct)/K); 1.157 - out->print_cr(" class space " 1.158 - SIZE_FORMAT "K, used " SIZE_FORMAT "K," 1.159 - " reserved " SIZE_FORMAT "K", 1.160 - capacity_bytes_slow(ct)/K, used_bytes_slow(ct)/K, reserved_in_bytes(ct)/K); 1.161 - } 1.162 -#endif 1.163 + 1.164 + out->print_cr(" data space " 1.165 + SIZE_FORMAT "K, used " SIZE_FORMAT "K," 1.166 + " reserved " SIZE_FORMAT "K", 1.167 + allocated_capacity_bytes(nct)/K, 1.168 + allocated_used_bytes(nct)/K, 1.169 + reserved_in_bytes(nct)/K); 1.170 + out->print_cr(" class space " 1.171 + SIZE_FORMAT "K, used " SIZE_FORMAT "K," 1.172 + " reserved " SIZE_FORMAT "K", 1.173 + allocated_capacity_bytes(ct)/K, 1.174 + allocated_used_bytes(ct)/K, 1.175 + reserved_in_bytes(ct)/K); 1.176 } 1.177 1.178 // Print information for class space and data space separately. 1.179 @@ -2717,24 +2722,42 @@ 1.180 void MetaspaceAux::verify_capacity() { 1.181 #ifdef ASSERT 1.182 size_t running_sum_capacity_bytes = allocated_capacity_bytes(); 1.183 - // For purposes of the running sum of used, verify against capacity 1.184 + // For purposes of the running sum of capacity, verify against capacity 1.185 size_t capacity_in_use_bytes = capacity_bytes_slow(); 1.186 assert(running_sum_capacity_bytes == capacity_in_use_bytes, 1.187 err_msg("allocated_capacity_words() * BytesPerWord " SIZE_FORMAT 1.188 " capacity_bytes_slow()" SIZE_FORMAT, 1.189 running_sum_capacity_bytes, capacity_in_use_bytes)); 1.190 + for (Metaspace::MetadataType i = Metaspace::ClassType; 1.191 + i < Metaspace:: MetadataTypeCount; 1.192 + i = (Metaspace::MetadataType)(i + 1)) { 1.193 + size_t capacity_in_use_bytes = capacity_bytes_slow(i); 1.194 + assert(allocated_capacity_bytes(i) == capacity_in_use_bytes, 1.195 + err_msg("allocated_capacity_bytes(%u) " SIZE_FORMAT 1.196 + " capacity_bytes_slow(%u)" SIZE_FORMAT, 1.197 + i, allocated_capacity_bytes(i), i, capacity_in_use_bytes)); 1.198 + } 1.199 #endif 1.200 } 1.201 1.202 void MetaspaceAux::verify_used() { 1.203 #ifdef ASSERT 1.204 size_t running_sum_used_bytes = allocated_used_bytes(); 1.205 - // For purposes of the running sum of used, verify against capacity 1.206 + // For purposes of the running sum of used, verify against used 1.207 size_t used_in_use_bytes = used_bytes_slow(); 1.208 assert(allocated_used_bytes() == used_in_use_bytes, 1.209 err_msg("allocated_used_bytes() " SIZE_FORMAT 1.210 - " used_bytes_slow()()" SIZE_FORMAT, 1.211 + " used_bytes_slow()" SIZE_FORMAT, 1.212 allocated_used_bytes(), used_in_use_bytes)); 1.213 + for (Metaspace::MetadataType i = Metaspace::ClassType; 1.214 + i < Metaspace:: MetadataTypeCount; 1.215 + i = (Metaspace::MetadataType)(i + 1)) { 1.216 + size_t used_in_use_bytes = used_bytes_slow(i); 1.217 + assert(allocated_used_bytes(i) == used_in_use_bytes, 1.218 + err_msg("allocated_used_bytes(%u) " SIZE_FORMAT 1.219 + " used_bytes_slow(%u)" SIZE_FORMAT, 1.220 + i, allocated_used_bytes(i), i, used_in_use_bytes)); 1.221 + } 1.222 #endif 1.223 } 1.224 1.225 @@ -2835,7 +2858,7 @@ 1.226 assert(space_list() != NULL, 1.227 "Metadata VirtualSpaceList has not been initialized"); 1.228 1.229 - _vsm = new SpaceManager(lock, space_list()); 1.230 + _vsm = new SpaceManager(Metaspace::NonClassType, lock, space_list()); 1.231 if (_vsm == NULL) { 1.232 return; 1.233 } 1.234 @@ -2849,7 +2872,7 @@ 1.235 "Class VirtualSpaceList has not been initialized"); 1.236 1.237 // Allocate SpaceManager for classes. 1.238 - _class_vsm = new SpaceManager(lock, class_space_list()); 1.239 + _class_vsm = new SpaceManager(Metaspace::ClassType, lock, class_space_list()); 1.240 if (_class_vsm == NULL) { 1.241 return; 1.242 }