Tue, 22 Oct 2013 12:03:50 -0700
Merge
1.1 --- a/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp Mon Oct 21 14:38:11 2013 -0700 1.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp Tue Oct 22 12:03:50 2013 -0700 1.3 @@ -187,19 +187,23 @@ 1.4 size_t code_root_elems() const { return _code_root_elems; } 1.5 1.6 void print_rs_mem_info_on(outputStream * out, size_t total) { 1.7 - out->print_cr(" %8dK (%5.1f%%) by %zd %s regions", round_to_K(rs_mem_size()), rs_mem_size_percent_of(total), amount(), _name); 1.8 + out->print_cr(" "SIZE_FORMAT_W(8)"K (%5.1f%%) by "SIZE_FORMAT" %s regions", 1.9 + round_to_K(rs_mem_size()), rs_mem_size_percent_of(total), amount(), _name); 1.10 } 1.11 1.12 void print_cards_occupied_info_on(outputStream * out, size_t total) { 1.13 - out->print_cr(" %8d (%5.1f%%) entries by %zd %s regions", cards_occupied(), cards_occupied_percent_of(total), amount(), _name); 1.14 + out->print_cr(" "SIZE_FORMAT_W(8)" (%5.1f%%) entries by "SIZE_FORMAT" %s regions", 1.15 + cards_occupied(), cards_occupied_percent_of(total), amount(), _name); 1.16 } 1.17 1.18 void print_code_root_mem_info_on(outputStream * out, size_t total) { 1.19 - out->print_cr(" %8dK (%5.1f%%) by %zd %s regions", round_to_K(code_root_mem_size()), code_root_mem_size_percent_of(total), amount(), _name); 1.20 + out->print_cr(" "SIZE_FORMAT_W(8)"K (%5.1f%%) by "SIZE_FORMAT" %s regions", 1.21 + round_to_K(code_root_mem_size()), code_root_mem_size_percent_of(total), amount(), _name); 1.22 } 1.23 1.24 void print_code_root_elems_info_on(outputStream * out, size_t total) { 1.25 - out->print_cr(" %8d (%5.1f%%) elements by %zd %s regions", code_root_elems(), code_root_elems_percent_of(total), amount(), _name); 1.26 + out->print_cr(" "SIZE_FORMAT_W(8)" (%5.1f%%) elements by "SIZE_FORMAT" %s regions", 1.27 + code_root_elems(), code_root_elems_percent_of(total), amount(), _name); 1.28 } 1.29 }; 1.30 1.31 @@ -327,14 +331,14 @@ 1.32 out->print_cr("\n Recent concurrent refinement statistics"); 1.33 out->print_cr(" Processed "SIZE_FORMAT" cards", 1.34 num_concurrent_refined_cards()); 1.35 - out->print_cr(" Of %d completed buffers:", num_processed_buf_total()); 1.36 - out->print_cr(" %8d (%5.1f%%) by concurrent RS threads.", 1.37 + out->print_cr(" Of "SIZE_FORMAT" completed buffers:", num_processed_buf_total()); 1.38 + out->print_cr(" "SIZE_FORMAT_W(8)" (%5.1f%%) by concurrent RS threads.", 1.39 num_processed_buf_total(), 1.40 percent_of(num_processed_buf_rs_threads(), num_processed_buf_total())); 1.41 - out->print_cr(" %8d (%5.1f%%) by mutator threads.", 1.42 + out->print_cr(" "SIZE_FORMAT_W(8)" (%5.1f%%) by mutator threads.", 1.43 num_processed_buf_mutator(), 1.44 percent_of(num_processed_buf_mutator(), num_processed_buf_total())); 1.45 - out->print_cr(" Did %d coarsenings.", num_coarsenings()); 1.46 + out->print_cr(" Did "SIZE_FORMAT" coarsenings.", num_coarsenings()); 1.47 out->print_cr(" Concurrent RS threads times (s)"); 1.48 out->print(" "); 1.49 for (uint i = 0; i < _num_vtimes; i++) {
2.1 --- a/src/share/vm/memory/metaspace.cpp Mon Oct 21 14:38:11 2013 -0700 2.2 +++ b/src/share/vm/memory/metaspace.cpp Tue Oct 22 12:03:50 2013 -0700 2.3 @@ -75,8 +75,7 @@ 2.4 ClassSmallChunk = 256, 2.5 SmallChunk = 512, 2.6 ClassMediumChunk = 4 * K, 2.7 - MediumChunk = 8 * K, 2.8 - HumongousChunkGranularity = 8 2.9 + MediumChunk = 8 * K 2.10 }; 2.11 2.12 static ChunkIndex next_chunk_index(ChunkIndex i) { 2.13 @@ -92,6 +91,7 @@ 2.14 2.15 // Manages the global free lists of chunks. 2.16 class ChunkManager : public CHeapObj<mtInternal> { 2.17 + friend class TestVirtualSpaceNodeTest; 2.18 2.19 // Free list of chunks of different sizes. 2.20 // SpecializedChunk 2.21 @@ -257,6 +257,8 @@ 2.22 // VirtualSpace 2.23 Metachunk* first_chunk() { return (Metachunk*) bottom(); } 2.24 2.25 + // Committed but unused space in the virtual space 2.26 + size_t free_words_in_vs() const; 2.27 public: 2.28 2.29 VirtualSpaceNode(size_t byte_size); 2.30 @@ -301,7 +303,6 @@ 2.31 // used and capacity in this single entry in the list 2.32 size_t used_words_in_vs() const; 2.33 size_t capacity_words_in_vs() const; 2.34 - size_t free_words_in_vs() const; 2.35 2.36 bool initialize(); 2.37 2.38 @@ -319,6 +320,13 @@ 2.39 // in the node from any freelist. 2.40 void purge(ChunkManager* chunk_manager); 2.41 2.42 + // If an allocation doesn't fit in the current node a new node is created. 2.43 + // Allocate chunks out of the remaining committed space in this node 2.44 + // to avoid wasting that memory. 2.45 + // This always adds up because all the chunk sizes are multiples of 2.46 + // the smallest chunk size. 2.47 + void retire(ChunkManager* chunk_manager); 2.48 + 2.49 #ifdef ASSERT 2.50 // Debug support 2.51 void mangle(); 2.52 @@ -461,6 +469,10 @@ 2.53 // and is typically followed by the allocation of a chunk. 2.54 bool create_new_virtual_space(size_t vs_word_size); 2.55 2.56 + // Chunk up the unused committed space in the current 2.57 + // virtual space and add the chunks to the free list. 2.58 + void retire_current_virtual_space(); 2.59 + 2.60 public: 2.61 VirtualSpaceList(size_t word_size); 2.62 VirtualSpaceList(ReservedSpace rs); 2.63 @@ -624,10 +636,12 @@ 2.64 bool is_class() { return _mdtype == Metaspace::ClassType; } 2.65 2.66 // Accessors 2.67 - size_t specialized_chunk_size() { return SpecializedChunk; } 2.68 - size_t small_chunk_size() { return (size_t) is_class() ? ClassSmallChunk : SmallChunk; } 2.69 - size_t medium_chunk_size() { return (size_t) is_class() ? ClassMediumChunk : MediumChunk; } 2.70 - size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; } 2.71 + size_t specialized_chunk_size() { return (size_t) is_class() ? ClassSpecializedChunk : SpecializedChunk; } 2.72 + size_t small_chunk_size() { return (size_t) is_class() ? ClassSmallChunk : SmallChunk; } 2.73 + size_t medium_chunk_size() { return (size_t) is_class() ? ClassMediumChunk : MediumChunk; } 2.74 + size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; } 2.75 + 2.76 + size_t smallest_chunk_size() { return specialized_chunk_size(); } 2.77 2.78 size_t allocated_blocks_words() const { return _allocated_blocks_words; } 2.79 size_t allocated_blocks_bytes() const { return _allocated_blocks_words * BytesPerWord; } 2.80 @@ -1056,6 +1070,35 @@ 2.81 #endif 2.82 } 2.83 2.84 +void VirtualSpaceList::retire_current_virtual_space() { 2.85 + assert_lock_strong(SpaceManager::expand_lock()); 2.86 + 2.87 + VirtualSpaceNode* vsn = current_virtual_space(); 2.88 + 2.89 + ChunkManager* cm = is_class() ? Metaspace::chunk_manager_class() : 2.90 + Metaspace::chunk_manager_metadata(); 2.91 + 2.92 + vsn->retire(cm); 2.93 +} 2.94 + 2.95 +void VirtualSpaceNode::retire(ChunkManager* chunk_manager) { 2.96 + for (int i = (int)MediumIndex; i >= (int)ZeroIndex; --i) { 2.97 + ChunkIndex index = (ChunkIndex)i; 2.98 + size_t chunk_size = chunk_manager->free_chunks(index)->size(); 2.99 + 2.100 + while (free_words_in_vs() >= chunk_size) { 2.101 + DEBUG_ONLY(verify_container_count();) 2.102 + Metachunk* chunk = get_chunk_vs(chunk_size); 2.103 + assert(chunk != NULL, "allocation should have been successful"); 2.104 + 2.105 + chunk_manager->return_chunks(index, chunk); 2.106 + chunk_manager->inc_free_chunks_total(chunk_size); 2.107 + DEBUG_ONLY(verify_container_count();) 2.108 + } 2.109 + } 2.110 + assert(free_words_in_vs() == 0, "should be empty now"); 2.111 +} 2.112 + 2.113 VirtualSpaceList::VirtualSpaceList(size_t word_size) : 2.114 _is_class(false), 2.115 _virtual_space_list(NULL), 2.116 @@ -1181,6 +1224,7 @@ 2.117 if (vs_expanded) { 2.118 return true; 2.119 } 2.120 + retire_current_virtual_space(); 2.121 2.122 // Get another virtual space. 2.123 size_t grow_vs_words = MAX2((size_t)VirtualSpaceSize, preferred_words); 2.124 @@ -1902,12 +1946,12 @@ 2.125 chunk_word_size = medium_chunk_size(); 2.126 } 2.127 2.128 - // Might still need a humongous chunk. Enforce an 2.129 - // eight word granularity to facilitate reuse (some 2.130 - // wastage but better chance of reuse). 2.131 + // Might still need a humongous chunk. Enforce 2.132 + // humongous allocations sizes to be aligned up to 2.133 + // the smallest chunk size. 2.134 size_t if_humongous_sized_chunk = 2.135 align_size_up(word_size + Metachunk::overhead(), 2.136 - HumongousChunkGranularity); 2.137 + smallest_chunk_size()); 2.138 chunk_word_size = 2.139 MAX2((size_t) chunk_word_size, if_humongous_sized_chunk); 2.140 2.141 @@ -2151,10 +2195,10 @@ 2.142 } 2.143 assert(humongous_chunks->word_size() == (size_t) 2.144 align_size_up(humongous_chunks->word_size(), 2.145 - HumongousChunkGranularity), 2.146 + smallest_chunk_size()), 2.147 err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT 2.148 " granularity %d", 2.149 - humongous_chunks->word_size(), HumongousChunkGranularity)); 2.150 + humongous_chunks->word_size(), smallest_chunk_size())); 2.151 Metachunk* next_humongous_chunks = humongous_chunks->next(); 2.152 humongous_chunks->container()->dec_container_count(); 2.153 chunk_manager()->humongous_dictionary()->return_chunk(humongous_chunks); 2.154 @@ -3301,9 +3345,7 @@ 2.155 } 2.156 2.157 if (result == NULL) { 2.158 - report_metadata_oome(loader_data, word_size, mdtype, THREAD); 2.159 - // Will not reach here. 2.160 - return NULL; 2.161 + report_metadata_oome(loader_data, word_size, mdtype, CHECK_NULL); 2.162 } 2.163 2.164 // Zero initialize. 2.165 @@ -3494,4 +3536,94 @@ 2.166 TestMetaspaceAuxTest::test(); 2.167 } 2.168 2.169 +class TestVirtualSpaceNodeTest { 2.170 + static void chunk_up(size_t words_left, size_t& num_medium_chunks, 2.171 + size_t& num_small_chunks, 2.172 + size_t& num_specialized_chunks) { 2.173 + num_medium_chunks = words_left / MediumChunk; 2.174 + words_left = words_left % MediumChunk; 2.175 + 2.176 + num_small_chunks = words_left / SmallChunk; 2.177 + words_left = words_left % SmallChunk; 2.178 + // how many specialized chunks can we get? 2.179 + num_specialized_chunks = words_left / SpecializedChunk; 2.180 + assert(words_left % SpecializedChunk == 0, "should be nothing left"); 2.181 + } 2.182 + 2.183 + public: 2.184 + static void test() { 2.185 + MutexLockerEx ml(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); 2.186 + const size_t vsn_test_size_words = MediumChunk * 4; 2.187 + const size_t vsn_test_size_bytes = vsn_test_size_words * BytesPerWord; 2.188 + 2.189 + // The chunk sizes must be multiples of eachother, or this will fail 2.190 + STATIC_ASSERT(MediumChunk % SmallChunk == 0); 2.191 + STATIC_ASSERT(SmallChunk % SpecializedChunk == 0); 2.192 + 2.193 + { // No committed memory in VSN 2.194 + ChunkManager cm(SpecializedChunk, SmallChunk, MediumChunk); 2.195 + VirtualSpaceNode vsn(vsn_test_size_bytes); 2.196 + vsn.initialize(); 2.197 + vsn.retire(&cm); 2.198 + assert(cm.sum_free_chunks_count() == 0, "did not commit any memory in the VSN"); 2.199 + } 2.200 + 2.201 + { // All of VSN is committed, half is used by chunks 2.202 + ChunkManager cm(SpecializedChunk, SmallChunk, MediumChunk); 2.203 + VirtualSpaceNode vsn(vsn_test_size_bytes); 2.204 + vsn.initialize(); 2.205 + vsn.expand_by(vsn_test_size_words, vsn_test_size_words); 2.206 + vsn.get_chunk_vs(MediumChunk); 2.207 + vsn.get_chunk_vs(MediumChunk); 2.208 + vsn.retire(&cm); 2.209 + assert(cm.sum_free_chunks_count() == 2, "should have been memory left for 2 medium chunks"); 2.210 + assert(cm.sum_free_chunks() == 2*MediumChunk, "sizes should add up"); 2.211 + } 2.212 + 2.213 + { // 4 pages of VSN is committed, some is used by chunks 2.214 + ChunkManager cm(SpecializedChunk, SmallChunk, MediumChunk); 2.215 + VirtualSpaceNode vsn(vsn_test_size_bytes); 2.216 + const size_t page_chunks = 4 * (size_t)os::vm_page_size() / BytesPerWord; 2.217 + assert(page_chunks < MediumChunk, "Test expects medium chunks to be at least 4*page_size"); 2.218 + vsn.initialize(); 2.219 + vsn.expand_by(page_chunks, page_chunks); 2.220 + vsn.get_chunk_vs(SmallChunk); 2.221 + vsn.get_chunk_vs(SpecializedChunk); 2.222 + vsn.retire(&cm); 2.223 + 2.224 + // committed - used = words left to retire 2.225 + const size_t words_left = page_chunks - SmallChunk - SpecializedChunk; 2.226 + 2.227 + size_t num_medium_chunks, num_small_chunks, num_spec_chunks; 2.228 + chunk_up(words_left, num_medium_chunks, num_small_chunks, num_spec_chunks); 2.229 + 2.230 + assert(num_medium_chunks == 0, "should not get any medium chunks"); 2.231 + assert(cm.sum_free_chunks_count() == (num_small_chunks + num_spec_chunks), "should be space for 3 chunks"); 2.232 + assert(cm.sum_free_chunks() == words_left, "sizes should add up"); 2.233 + } 2.234 + 2.235 + { // Half of VSN is committed, a humongous chunk is used 2.236 + ChunkManager cm(SpecializedChunk, SmallChunk, MediumChunk); 2.237 + VirtualSpaceNode vsn(vsn_test_size_bytes); 2.238 + vsn.initialize(); 2.239 + vsn.expand_by(MediumChunk * 2, MediumChunk * 2); 2.240 + vsn.get_chunk_vs(MediumChunk + SpecializedChunk); // Humongous chunks will be aligned up to MediumChunk + SpecializedChunk 2.241 + vsn.retire(&cm); 2.242 + 2.243 + const size_t words_left = MediumChunk * 2 - (MediumChunk + SpecializedChunk); 2.244 + size_t num_medium_chunks, num_small_chunks, num_spec_chunks; 2.245 + chunk_up(words_left, num_medium_chunks, num_small_chunks, num_spec_chunks); 2.246 + 2.247 + assert(num_medium_chunks == 0, "should not get any medium chunks"); 2.248 + assert(cm.sum_free_chunks_count() == (num_small_chunks + num_spec_chunks), "should be space for 3 chunks"); 2.249 + assert(cm.sum_free_chunks() == words_left, "sizes should add up"); 2.250 + } 2.251 + 2.252 + } 2.253 +}; 2.254 + 2.255 +void TestVirtualSpaceNode_test() { 2.256 + TestVirtualSpaceNodeTest::test(); 2.257 +} 2.258 + 2.259 #endif
3.1 --- a/src/share/vm/prims/jni.cpp Mon Oct 21 14:38:11 2013 -0700 3.2 +++ b/src/share/vm/prims/jni.cpp Tue Oct 22 12:03:50 2013 -0700 3.3 @@ -5060,6 +5060,7 @@ 3.4 void TestVirtualSpace_test(); 3.5 void TestMetaspaceAux_test(); 3.6 void TestMetachunk_test(); 3.7 +void TestVirtualSpaceNode_test(); 3.8 #if INCLUDE_ALL_GCS 3.9 void TestG1BiasedArray_test(); 3.10 #endif 3.11 @@ -5072,6 +5073,7 @@ 3.12 run_unit_test(TestVirtualSpace_test()); 3.13 run_unit_test(TestMetaspaceAux_test()); 3.14 run_unit_test(TestMetachunk_test()); 3.15 + run_unit_test(TestVirtualSpaceNode_test()); 3.16 run_unit_test(GlobalDefinitions::test_globals()); 3.17 run_unit_test(GCTimerAllTest::all()); 3.18 run_unit_test(arrayOopDesc::test_max_array_length());
4.1 --- a/src/share/vm/prims/jvmtiImpl.cpp Mon Oct 21 14:38:11 2013 -0700 4.2 +++ b/src/share/vm/prims/jvmtiImpl.cpp Tue Oct 22 12:03:50 2013 -0700 4.3 @@ -225,18 +225,20 @@ 4.4 _method = NULL; 4.5 _bci = 0; 4.6 _class_loader = NULL; 4.7 -#ifdef CHECK_UNHANDLED_OOPS 4.8 - // This one is always allocated with new, but check it just in case. 4.9 - Thread *thread = Thread::current(); 4.10 - if (thread->is_in_stack((address)&_method)) { 4.11 - thread->allow_unhandled_oop((oop*)&_method); 4.12 - } 4.13 -#endif // CHECK_UNHANDLED_OOPS 4.14 } 4.15 4.16 JvmtiBreakpoint::JvmtiBreakpoint(Method* m_method, jlocation location) { 4.17 _method = m_method; 4.18 _class_loader = _method->method_holder()->class_loader_data()->class_loader(); 4.19 +#ifdef CHECK_UNHANDLED_OOPS 4.20 + // _class_loader can't be wrapped in a Handle, because JvmtiBreakpoint:s are 4.21 + // eventually allocated on the heap. 4.22 + // 4.23 + // The code handling JvmtiBreakpoint:s allocated on the stack can't be 4.24 + // interrupted by a GC until _class_loader is reachable by the GC via the 4.25 + // oops_do method. 4.26 + Thread::current()->allow_unhandled_oop(&_class_loader); 4.27 +#endif // CHECK_UNHANDLED_OOPS 4.28 assert(_method != NULL, "_method != NULL"); 4.29 _bci = (int) location; 4.30 assert(_bci >= 0, "_bci >= 0");
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/gc/TestSystemGC.java Tue Oct 22 12:03:50 2013 -0700 5.3 @@ -0,0 +1,46 @@ 5.4 +/* 5.5 +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 5.6 +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 +* 5.8 +* This code is free software; you can redistribute it and/or modify it 5.9 +* under the terms of the GNU General Public License version 2 only, as 5.10 +* published by the Free Software Foundation. 5.11 +* 5.12 +* This code is distributed in the hope that it will be useful, but WITHOUT 5.13 +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.14 +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.15 +* version 2 for more details (a copy is included in the LICENSE file that 5.16 +* accompanied this code). 5.17 +* 5.18 +* You should have received a copy of the GNU General Public License version 5.19 +* 2 along with this work; if not, write to the Free Software Foundation, 5.20 +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.21 +* 5.22 +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.23 +* or visit www.oracle.com if you need additional information or have any 5.24 +* questions. 5.25 +*/ 5.26 + 5.27 +/* 5.28 + * @test TestSystemGC 5.29 + * @key gc 5.30 + * @summary Runs System.gc() with different flags. 5.31 + * @run main/othervm TestSystemGC 5.32 + * @run main/othervm -XX:+UseSerialGC TestSystemGC 5.33 + * @run main/othervm -XX:+UseParNewGC TestSystemGC 5.34 + * @run main/othervm -XX:+UseParallelGC TestSystemGC 5.35 + * @run main/othervm -XX:+UseParallelGC -XX:-UseParallelOldGC TestSystemGC 5.36 + * @run main/othervm -XX:+UseConcMarkSweepGC TestSystemGC 5.37 + * @run main/othervm -XX:+UseConcMarkSweepGC -XX:+ExplicitGCInvokesConcurrent TestSystemGC 5.38 + * @run main/othervm -XX:+UseConcMarkSweepGC -XX:+ExplicitGCInvokesConcurrent -XX:-UseParNewGC TestSystemGC 5.39 + * @run main/othervm -XX:+UseG1GC TestSystemGC 5.40 + * @run main/othervm -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent TestSystemGC 5.41 + * @run main/othervm -XX:+UseLargePages TestSystemGC 5.42 + * @run main/othervm -XX:+UseLargePages -XX:+UseLargePagesInMetaspace TestSystemGC 5.43 + */ 5.44 + 5.45 +public class TestSystemGC { 5.46 + public static void main(String args[]) throws Exception { 5.47 + System.gc(); 5.48 + } 5.49 +}