Fri, 04 Oct 2013 13:37:25 -0700
Merge
1.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp Thu Oct 03 10:35:32 2013 -0700 1.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp Fri Oct 04 13:37:25 2013 -0700 1.3 @@ -81,7 +81,7 @@ 1.4 size_t* marked_bytes_array, 1.5 BitMap* task_card_bm) { 1.6 G1CollectedHeap* g1h = _g1h; 1.7 - CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set()); 1.8 + CardTableModRefBS* ct_bs = g1h->g1_barrier_set(); 1.9 1.10 HeapWord* start = mr.start(); 1.11 HeapWord* end = mr.end();
2.1 --- a/src/share/vm/gc_implementation/g1/g1CardCounts.cpp Thu Oct 03 10:35:32 2013 -0700 2.2 +++ b/src/share/vm/gc_implementation/g1/g1CardCounts.cpp Fri Oct 04 13:37:25 2013 -0700 2.3 @@ -65,9 +65,7 @@ 2.4 // threshold limit is no more than this. 2.5 guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity"); 2.6 2.7 - ModRefBarrierSet* bs = _g1h->mr_bs(); 2.8 - guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition"); 2.9 - _ct_bs = (CardTableModRefBS*)bs; 2.10 + _ct_bs = _g1h->g1_barrier_set(); 2.11 _ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start()); 2.12 2.13 // Allocate/Reserve the counts table
3.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Oct 03 10:35:32 2013 -0700 3.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Oct 04 13:37:25 2013 -0700 3.3 @@ -125,10 +125,8 @@ 3.4 int _histo[256]; 3.5 public: 3.6 ClearLoggedCardTableEntryClosure() : 3.7 - _calls(0) 3.8 + _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) 3.9 { 3.10 - _g1h = G1CollectedHeap::heap(); 3.11 - _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); 3.12 for (int i = 0; i < 256; i++) _histo[i] = 0; 3.13 } 3.14 bool do_card_ptr(jbyte* card_ptr, int worker_i) { 3.15 @@ -158,11 +156,8 @@ 3.16 CardTableModRefBS* _ctbs; 3.17 public: 3.18 RedirtyLoggedCardTableEntryClosure() : 3.19 - _calls(0) 3.20 - { 3.21 - _g1h = G1CollectedHeap::heap(); 3.22 - _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); 3.23 - } 3.24 + _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) {} 3.25 + 3.26 bool do_card_ptr(jbyte* card_ptr, int worker_i) { 3.27 if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { 3.28 _calls++; 3.29 @@ -478,7 +473,7 @@ 3.30 3.31 void G1CollectedHeap::check_ct_logs_at_safepoint() { 3.32 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); 3.33 - CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); 3.34 + CardTableModRefBS* ct_bs = g1_barrier_set(); 3.35 3.36 // Count the dirty cards at the start. 3.37 CountNonCleanMemRegionClosure count1(this); 3.38 @@ -1205,7 +1200,7 @@ 3.39 }; 3.40 3.41 void G1CollectedHeap::clear_rsets_post_compaction() { 3.42 - PostMCRemSetClearClosure rs_clear(this, mr_bs()); 3.43 + PostMCRemSetClearClosure rs_clear(this, g1_barrier_set()); 3.44 heap_region_iterate(&rs_clear); 3.45 } 3.46 3.47 @@ -1777,7 +1772,6 @@ 3.48 } 3.49 3.50 bool G1CollectedHeap::expand(size_t expand_bytes) { 3.51 - size_t old_mem_size = _g1_storage.committed_size(); 3.52 size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); 3.53 aligned_expand_bytes = align_size_up(aligned_expand_bytes, 3.54 HeapRegion::GrainBytes); 3.55 @@ -1787,6 +1781,13 @@ 3.56 ergo_format_byte("attempted expansion amount"), 3.57 expand_bytes, aligned_expand_bytes); 3.58 3.59 + if (_g1_storage.uncommitted_size() == 0) { 3.60 + ergo_verbose0(ErgoHeapSizing, 3.61 + "did not expand the heap", 3.62 + ergo_format_reason("heap already fully expanded")); 3.63 + return false; 3.64 + } 3.65 + 3.66 // First commit the memory. 3.67 HeapWord* old_end = (HeapWord*) _g1_storage.high(); 3.68 bool successful = _g1_storage.expand_by(aligned_expand_bytes); 3.69 @@ -1845,7 +1846,6 @@ 3.70 } 3.71 3.72 void G1CollectedHeap::shrink_helper(size_t shrink_bytes) { 3.73 - size_t old_mem_size = _g1_storage.committed_size(); 3.74 size_t aligned_shrink_bytes = 3.75 ReservedSpace::page_align_size_down(shrink_bytes); 3.76 aligned_shrink_bytes = align_size_down(aligned_shrink_bytes, 3.77 @@ -2045,20 +2045,13 @@ 3.78 // Create the gen rem set (and barrier set) for the entire reserved region. 3.79 _rem_set = collector_policy()->create_rem_set(_reserved, 2); 3.80 set_barrier_set(rem_set()->bs()); 3.81 - if (barrier_set()->is_a(BarrierSet::ModRef)) { 3.82 - _mr_bs = (ModRefBarrierSet*)_barrier_set; 3.83 - } else { 3.84 - vm_exit_during_initialization("G1 requires a mod ref bs."); 3.85 + if (!barrier_set()->is_a(BarrierSet::G1SATBCTLogging)) { 3.86 + vm_exit_during_initialization("G1 requires a G1SATBLoggingCardTableModRefBS"); 3.87 return JNI_ENOMEM; 3.88 } 3.89 3.90 // Also create a G1 rem set. 3.91 - if (mr_bs()->is_a(BarrierSet::CardTableModRef)) { 3.92 - _g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs()); 3.93 - } else { 3.94 - vm_exit_during_initialization("G1 requires a cardtable mod ref bs."); 3.95 - return JNI_ENOMEM; 3.96 - } 3.97 + _g1_rem_set = new G1RemSet(this, g1_barrier_set()); 3.98 3.99 // Carve out the G1 part of the heap. 3.100 3.101 @@ -3681,6 +3674,11 @@ 3.102 assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer"); 3.103 // Fill TLAB's and such 3.104 ensure_parsability(true); 3.105 + 3.106 + if (G1SummarizeRSetStats && (G1SummarizeRSetStatsPeriod > 0) && 3.107 + (total_collections() % G1SummarizeRSetStatsPeriod == 0)) { 3.108 + g1_rem_set()->print_periodic_summary_info("Before GC RS summary"); 3.109 + } 3.110 } 3.111 3.112 void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) { 3.113 @@ -3689,7 +3687,7 @@ 3.114 (G1SummarizeRSetStatsPeriod > 0) && 3.115 // we are at the end of the GC. Total collections has already been increased. 3.116 ((total_collections() - 1) % G1SummarizeRSetStatsPeriod == 0)) { 3.117 - g1_rem_set()->print_periodic_summary_info(); 3.118 + g1_rem_set()->print_periodic_summary_info("After GC RS summary"); 3.119 } 3.120 3.121 // FIXME: what is this about? 3.122 @@ -4550,7 +4548,7 @@ 3.123 : _g1h(g1h), 3.124 _refs(g1h->task_queue(queue_num)), 3.125 _dcq(&g1h->dirty_card_queue_set()), 3.126 - _ct_bs((CardTableModRefBS*)_g1h->barrier_set()), 3.127 + _ct_bs(g1h->g1_barrier_set()), 3.128 _g1_rem(g1h->g1_rem_set()), 3.129 _hash_seed(17), _queue_num(queue_num), 3.130 _term_attempts(0), 3.131 @@ -5979,11 +5977,11 @@ 3.132 } 3.133 3.134 class G1ParCleanupCTTask : public AbstractGangTask { 3.135 - CardTableModRefBS* _ct_bs; 3.136 + G1SATBCardTableModRefBS* _ct_bs; 3.137 G1CollectedHeap* _g1h; 3.138 HeapRegion* volatile _su_head; 3.139 public: 3.140 - G1ParCleanupCTTask(CardTableModRefBS* ct_bs, 3.141 + G1ParCleanupCTTask(G1SATBCardTableModRefBS* ct_bs, 3.142 G1CollectedHeap* g1h) : 3.143 AbstractGangTask("G1 Par Cleanup CT Task"), 3.144 _ct_bs(ct_bs), _g1h(g1h) { } 3.145 @@ -6006,9 +6004,9 @@ 3.146 #ifndef PRODUCT 3.147 class G1VerifyCardTableCleanup: public HeapRegionClosure { 3.148 G1CollectedHeap* _g1h; 3.149 - CardTableModRefBS* _ct_bs; 3.150 + G1SATBCardTableModRefBS* _ct_bs; 3.151 public: 3.152 - G1VerifyCardTableCleanup(G1CollectedHeap* g1h, CardTableModRefBS* ct_bs) 3.153 + G1VerifyCardTableCleanup(G1CollectedHeap* g1h, G1SATBCardTableModRefBS* ct_bs) 3.154 : _g1h(g1h), _ct_bs(ct_bs) { } 3.155 virtual bool doHeapRegion(HeapRegion* r) { 3.156 if (r->is_survivor()) { 3.157 @@ -6022,7 +6020,7 @@ 3.158 3.159 void G1CollectedHeap::verify_not_dirty_region(HeapRegion* hr) { 3.160 // All of the region should be clean. 3.161 - CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); 3.162 + G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); 3.163 MemRegion mr(hr->bottom(), hr->end()); 3.164 ct_bs->verify_not_dirty_region(mr); 3.165 } 3.166 @@ -6035,13 +6033,13 @@ 3.167 // not dirty that area (one less thing to have to do while holding 3.168 // a lock). So we can only verify that [bottom(),pre_dummy_top()] 3.169 // is dirty. 3.170 - CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); 3.171 + G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); 3.172 MemRegion mr(hr->bottom(), hr->pre_dummy_top()); 3.173 ct_bs->verify_dirty_region(mr); 3.174 } 3.175 3.176 void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) { 3.177 - CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); 3.178 + G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); 3.179 for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) { 3.180 verify_dirty_region(hr); 3.181 } 3.182 @@ -6053,7 +6051,7 @@ 3.183 #endif 3.184 3.185 void G1CollectedHeap::cleanUpCardTable() { 3.186 - CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); 3.187 + G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); 3.188 double start = os::elapsedTime(); 3.189 3.190 {
4.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Oct 03 10:35:32 2013 -0700 4.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Oct 04 13:37:25 2013 -0700 4.3 @@ -31,6 +31,7 @@ 4.4 #include "gc_implementation/g1/g1HRPrinter.hpp" 4.5 #include "gc_implementation/g1/g1MonitoringSupport.hpp" 4.6 #include "gc_implementation/g1/g1RemSet.hpp" 4.7 +#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" 4.8 #include "gc_implementation/g1/g1YCTypes.hpp" 4.9 #include "gc_implementation/g1/heapRegionSeq.hpp" 4.10 #include "gc_implementation/g1/heapRegionSets.hpp" 4.11 @@ -791,8 +792,6 @@ 4.12 4.13 // The g1 remembered set of the heap. 4.14 G1RemSet* _g1_rem_set; 4.15 - // And it's mod ref barrier set, used to track updates for the above. 4.16 - ModRefBarrierSet* _mr_bs; 4.17 4.18 // A set of cards that cover the objects for which the Rsets should be updated 4.19 // concurrently after the collection. 4.20 @@ -1127,7 +1126,6 @@ 4.21 4.22 // The rem set and barrier set. 4.23 G1RemSet* g1_rem_set() const { return _g1_rem_set; } 4.24 - ModRefBarrierSet* mr_bs() const { return _mr_bs; } 4.25 4.26 unsigned get_gc_time_stamp() { 4.27 return _gc_time_stamp; 4.28 @@ -1346,6 +1344,10 @@ 4.29 4.30 virtual bool is_in_closed_subset(const void* p) const; 4.31 4.32 + G1SATBCardTableModRefBS* g1_barrier_set() { 4.33 + return (G1SATBCardTableModRefBS*) barrier_set(); 4.34 + } 4.35 + 4.36 // This resets the card table to all zeros. It is used after 4.37 // a collection pause which used the card table to claim cards. 4.38 void cleanUpCardTable(); 4.39 @@ -1875,7 +1877,7 @@ 4.40 G1CollectedHeap* _g1h; 4.41 RefToScanQueue* _refs; 4.42 DirtyCardQueue _dcq; 4.43 - CardTableModRefBS* _ct_bs; 4.44 + G1SATBCardTableModRefBS* _ct_bs; 4.45 G1RemSet* _g1_rem; 4.46 4.47 G1ParGCAllocBufferContainer _surviving_alloc_buffer; 4.48 @@ -1914,7 +1916,7 @@ 4.49 void add_to_undo_waste(size_t waste) { _undo_waste += waste; } 4.50 4.51 DirtyCardQueue& dirty_card_queue() { return _dcq; } 4.52 - CardTableModRefBS* ctbs() { return _ct_bs; } 4.53 + G1SATBCardTableModRefBS* ctbs() { return _ct_bs; } 4.54 4.55 template <class T> void immediate_rs_update(HeapRegion* from, T* p, int tid) { 4.56 if (!from->is_survivor()) {
5.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Thu Oct 03 10:35:32 2013 -0700 5.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Fri Oct 04 13:37:25 2013 -0700 5.3 @@ -134,7 +134,7 @@ 5.4 assert(containing_hr->is_in(end - 1), "it should also contain end - 1"); 5.5 5.6 MemRegion mr(start, end); 5.7 - ((CardTableModRefBS*)_g1h->barrier_set())->dirty(mr); 5.8 + g1_barrier_set()->dirty(mr); 5.9 } 5.10 5.11 inline RefToScanQueue* G1CollectedHeap::task_queue(int i) const {
6.1 --- a/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp Thu Oct 03 10:35:32 2013 -0700 6.2 +++ b/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp Fri Oct 04 13:37:25 2013 -0700 6.3 @@ -41,11 +41,11 @@ 6.4 private: 6.5 G1CollectedHeap* _g1; 6.6 DirtyCardQueue *_dcq; 6.7 - CardTableModRefBS* _ct_bs; 6.8 + G1SATBCardTableModRefBS* _ct_bs; 6.9 6.10 public: 6.11 UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) : 6.12 - _g1(g1), _ct_bs((CardTableModRefBS*)_g1->barrier_set()), _dcq(dcq) {} 6.13 + _g1(g1), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {} 6.14 6.15 virtual void do_oop(narrowOop* p) { do_oop_work(p); } 6.16 virtual void do_oop( oop* p) { do_oop_work(p); }
7.1 --- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Thu Oct 03 10:35:32 2013 -0700 7.2 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Fri Oct 04 13:37:25 2013 -0700 7.3 @@ -220,7 +220,7 @@ 7.4 public: 7.5 G1PrepareCompactClosure(CompactibleSpace* cs) 7.6 : _g1h(G1CollectedHeap::heap()), 7.7 - _mrbs(G1CollectedHeap::heap()->mr_bs()), 7.8 + _mrbs(_g1h->g1_barrier_set()), 7.9 _cp(NULL, cs, cs->initialize_threshold()), 7.10 _humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { } 7.11
8.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp Thu Oct 03 10:35:32 2013 -0700 8.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp Fri Oct 04 13:37:25 2013 -0700 8.3 @@ -83,7 +83,9 @@ 8.4 for (uint i = 0; i < n_workers(); i++) { 8.5 _cset_rs_update_cl[i] = NULL; 8.6 } 8.7 - _prev_period_summary.initialize(this, n_workers()); 8.8 + if (G1SummarizeRSetStats) { 8.9 + _prev_period_summary.initialize(this); 8.10 + } 8.11 } 8.12 8.13 G1RemSet::~G1RemSet() { 8.14 @@ -109,7 +111,7 @@ 8.15 CodeBlobToOopClosure* _code_root_cl; 8.16 8.17 G1BlockOffsetSharedArray* _bot_shared; 8.18 - CardTableModRefBS *_ct_bs; 8.19 + G1SATBCardTableModRefBS *_ct_bs; 8.20 8.21 double _strong_code_root_scan_time_sec; 8.22 int _worker_i; 8.23 @@ -130,7 +132,7 @@ 8.24 { 8.25 _g1h = G1CollectedHeap::heap(); 8.26 _bot_shared = _g1h->bot_shared(); 8.27 - _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set()); 8.28 + _ct_bs = _g1h->g1_barrier_set(); 8.29 _block_size = MAX2<int>(G1RSetScanBlockSize, 1); 8.30 } 8.31 8.32 @@ -505,12 +507,7 @@ 8.33 ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) : 8.34 _g1h(G1CollectedHeap::heap()), 8.35 _region_bm(region_bm), _card_bm(card_bm), 8.36 - _ctbs(NULL) 8.37 - { 8.38 - ModRefBarrierSet* bs = _g1h->mr_bs(); 8.39 - guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition"); 8.40 - _ctbs = (CardTableModRefBS*)bs; 8.41 - } 8.42 + _ctbs(_g1h->g1_barrier_set()) {} 8.43 8.44 bool doHeapRegion(HeapRegion* r) { 8.45 if (!r->continuesHumongous()) { 8.46 @@ -731,19 +728,19 @@ 8.47 return has_refs_into_cset; 8.48 } 8.49 8.50 -void G1RemSet::print_periodic_summary_info() { 8.51 +void G1RemSet::print_periodic_summary_info(const char* header) { 8.52 G1RemSetSummary current; 8.53 - current.initialize(this, n_workers()); 8.54 + current.initialize(this); 8.55 8.56 _prev_period_summary.subtract_from(¤t); 8.57 - print_summary_info(&_prev_period_summary); 8.58 + print_summary_info(&_prev_period_summary, header); 8.59 8.60 _prev_period_summary.set(¤t); 8.61 } 8.62 8.63 void G1RemSet::print_summary_info() { 8.64 G1RemSetSummary current; 8.65 - current.initialize(this, n_workers()); 8.66 + current.initialize(this); 8.67 8.68 print_summary_info(¤t, " Cumulative RS summary"); 8.69 }
9.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp Thu Oct 03 10:35:32 2013 -0700 9.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp Fri Oct 04 13:37:25 2013 -0700 9.3 @@ -145,7 +145,7 @@ 9.4 virtual void print_summary_info(); 9.5 9.6 // Print accumulated summary info from the last time called. 9.7 - virtual void print_periodic_summary_info(); 9.8 + virtual void print_periodic_summary_info(const char* header); 9.9 9.10 // Prepare remembered set for verification. 9.11 virtual void prepare_for_verify();
10.1 --- a/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp Thu Oct 03 10:35:32 2013 -0700 10.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp Fri Oct 04 13:37:25 2013 -0700 10.3 @@ -77,12 +77,12 @@ 10.4 return _rs_threads_vtimes[thread]; 10.5 } 10.6 10.7 -void G1RemSetSummary::initialize(G1RemSet* remset, uint num_workers) { 10.8 +void G1RemSetSummary::initialize(G1RemSet* remset) { 10.9 assert(_rs_threads_vtimes == NULL, "just checking"); 10.10 assert(remset != NULL, "just checking"); 10.11 10.12 _remset = remset; 10.13 - _num_vtimes = num_workers; 10.14 + _num_vtimes = ConcurrentG1Refine::thread_num(); 10.15 _rs_threads_vtimes = NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC); 10.16 memset(_rs_threads_vtimes, 0, sizeof(double) * _num_vtimes); 10.17 10.18 @@ -125,25 +125,115 @@ 10.19 _sampling_thread_vtime = other->sampling_thread_vtime() - _sampling_thread_vtime; 10.20 } 10.21 10.22 +static double percent_of(size_t numerator, size_t denominator) { 10.23 + if (denominator != 0) { 10.24 + return (double)numerator / denominator * 100.0f; 10.25 + } else { 10.26 + return 0.0f; 10.27 + } 10.28 +} 10.29 + 10.30 +static size_t round_to_K(size_t value) { 10.31 + return value / K; 10.32 +} 10.33 + 10.34 +class RegionTypeCounter VALUE_OBJ_CLASS_SPEC { 10.35 +private: 10.36 + const char* _name; 10.37 + 10.38 + size_t _rs_mem_size; 10.39 + size_t _cards_occupied; 10.40 + size_t _amount; 10.41 + 10.42 + size_t _code_root_mem_size; 10.43 + size_t _code_root_elems; 10.44 + 10.45 + double rs_mem_size_percent_of(size_t total) { 10.46 + return percent_of(_rs_mem_size, total); 10.47 + } 10.48 + 10.49 + double cards_occupied_percent_of(size_t total) { 10.50 + return percent_of(_cards_occupied, total); 10.51 + } 10.52 + 10.53 + double code_root_mem_size_percent_of(size_t total) { 10.54 + return percent_of(_code_root_mem_size, total); 10.55 + } 10.56 + 10.57 + double code_root_elems_percent_of(size_t total) { 10.58 + return percent_of(_code_root_elems, total); 10.59 + } 10.60 + 10.61 + size_t amount() const { return _amount; } 10.62 + 10.63 +public: 10.64 + 10.65 + RegionTypeCounter(const char* name) : _name(name), _rs_mem_size(0), _cards_occupied(0), 10.66 + _amount(0), _code_root_mem_size(0), _code_root_elems(0) { } 10.67 + 10.68 + void add(size_t rs_mem_size, size_t cards_occupied, size_t code_root_mem_size, 10.69 + size_t code_root_elems) { 10.70 + _rs_mem_size += rs_mem_size; 10.71 + _cards_occupied += cards_occupied; 10.72 + _code_root_mem_size += code_root_mem_size; 10.73 + _code_root_elems += code_root_elems; 10.74 + _amount++; 10.75 + } 10.76 + 10.77 + size_t rs_mem_size() const { return _rs_mem_size; } 10.78 + size_t cards_occupied() const { return _cards_occupied; } 10.79 + 10.80 + size_t code_root_mem_size() const { return _code_root_mem_size; } 10.81 + size_t code_root_elems() const { return _code_root_elems; } 10.82 + 10.83 + void print_rs_mem_info_on(outputStream * out, size_t total) { 10.84 + out->print_cr(" %8dK (%5.1f%%) by %zd %s regions", round_to_K(rs_mem_size()), rs_mem_size_percent_of(total), amount(), _name); 10.85 + } 10.86 + 10.87 + void print_cards_occupied_info_on(outputStream * out, size_t total) { 10.88 + out->print_cr(" %8d (%5.1f%%) entries by %zd %s regions", cards_occupied(), cards_occupied_percent_of(total), amount(), _name); 10.89 + } 10.90 + 10.91 + void print_code_root_mem_info_on(outputStream * out, size_t total) { 10.92 + 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); 10.93 + } 10.94 + 10.95 + void print_code_root_elems_info_on(outputStream * out, size_t total) { 10.96 + out->print_cr(" %8d (%5.1f%%) elements by %zd %s regions", code_root_elems(), code_root_elems_percent_of(total), amount(), _name); 10.97 + } 10.98 +}; 10.99 + 10.100 + 10.101 class HRRSStatsIter: public HeapRegionClosure { 10.102 - size_t _occupied; 10.103 +private: 10.104 + RegionTypeCounter _young; 10.105 + RegionTypeCounter _humonguous; 10.106 + RegionTypeCounter _free; 10.107 + RegionTypeCounter _old; 10.108 + RegionTypeCounter _all; 10.109 10.110 - size_t _total_rs_mem_sz; 10.111 size_t _max_rs_mem_sz; 10.112 HeapRegion* _max_rs_mem_sz_region; 10.113 10.114 - size_t _total_code_root_mem_sz; 10.115 + size_t total_rs_mem_sz() const { return _all.rs_mem_size(); } 10.116 + size_t total_cards_occupied() const { return _all.cards_occupied(); } 10.117 + 10.118 + size_t max_rs_mem_sz() const { return _max_rs_mem_sz; } 10.119 + HeapRegion* max_rs_mem_sz_region() const { return _max_rs_mem_sz_region; } 10.120 + 10.121 size_t _max_code_root_mem_sz; 10.122 HeapRegion* _max_code_root_mem_sz_region; 10.123 + 10.124 + size_t total_code_root_mem_sz() const { return _all.code_root_mem_size(); } 10.125 + size_t total_code_root_elems() const { return _all.code_root_elems(); } 10.126 + 10.127 + size_t max_code_root_mem_sz() const { return _max_code_root_mem_sz; } 10.128 + HeapRegion* max_code_root_mem_sz_region() const { return _max_code_root_mem_sz_region; } 10.129 + 10.130 public: 10.131 - HRRSStatsIter() : 10.132 - _occupied(0), 10.133 - _total_rs_mem_sz(0), 10.134 - _max_rs_mem_sz(0), 10.135 - _max_rs_mem_sz_region(NULL), 10.136 - _total_code_root_mem_sz(0), 10.137 - _max_code_root_mem_sz(0), 10.138 - _max_code_root_mem_sz_region(NULL) 10.139 + HRRSStatsIter() : _all("All"), _young("Young"), _humonguous("Humonguous"), 10.140 + _free("Free"), _old("Old"), _max_code_root_mem_sz_region(NULL), _max_rs_mem_sz_region(NULL), 10.141 + _max_rs_mem_sz(0), _max_code_root_mem_sz(0) 10.142 {} 10.143 10.144 bool doHeapRegion(HeapRegion* r) { 10.145 @@ -156,46 +246,95 @@ 10.146 _max_rs_mem_sz = rs_mem_sz; 10.147 _max_rs_mem_sz_region = r; 10.148 } 10.149 - _total_rs_mem_sz += rs_mem_sz; 10.150 - 10.151 + size_t occupied_cards = hrrs->occupied(); 10.152 size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size(); 10.153 - if (code_root_mem_sz > _max_code_root_mem_sz) { 10.154 - _max_code_root_mem_sz = code_root_mem_sz; 10.155 + if (code_root_mem_sz > max_code_root_mem_sz()) { 10.156 _max_code_root_mem_sz_region = r; 10.157 } 10.158 - _total_code_root_mem_sz += code_root_mem_sz; 10.159 + size_t code_root_elems = hrrs->strong_code_roots_list_length(); 10.160 10.161 - size_t occ = hrrs->occupied(); 10.162 - _occupied += occ; 10.163 + RegionTypeCounter* current = NULL; 10.164 + if (r->is_young()) { 10.165 + current = &_young; 10.166 + } else if (r->isHumongous()) { 10.167 + current = &_humonguous; 10.168 + } else if (r->is_empty()) { 10.169 + current = &_free; 10.170 + } else { 10.171 + current = &_old; 10.172 + } 10.173 + current->add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems); 10.174 + _all.add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems); 10.175 + 10.176 return false; 10.177 } 10.178 - size_t total_rs_mem_sz() { return _total_rs_mem_sz; } 10.179 - size_t max_rs_mem_sz() { return _max_rs_mem_sz; } 10.180 - HeapRegion* max_rs_mem_sz_region() { return _max_rs_mem_sz_region; } 10.181 - size_t total_code_root_mem_sz() { return _total_code_root_mem_sz; } 10.182 - size_t max_code_root_mem_sz() { return _max_code_root_mem_sz; } 10.183 - HeapRegion* max_code_root_mem_sz_region() { return _max_code_root_mem_sz_region; } 10.184 - size_t occupied() { return _occupied; } 10.185 + 10.186 + void print_summary_on(outputStream* out) { 10.187 + RegionTypeCounter* counters[] = { &_young, &_humonguous, &_free, &_old, NULL }; 10.188 + 10.189 + out->print_cr("\n Current rem set statistics"); 10.190 + out->print_cr(" Total per region rem sets sizes = "SIZE_FORMAT"K." 10.191 + " Max = "SIZE_FORMAT"K.", 10.192 + round_to_K(total_rs_mem_sz()), round_to_K(max_rs_mem_sz())); 10.193 + for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { 10.194 + (*current)->print_rs_mem_info_on(out, total_rs_mem_sz()); 10.195 + } 10.196 + 10.197 + out->print_cr(" Static structures = "SIZE_FORMAT"K," 10.198 + " free_lists = "SIZE_FORMAT"K.", 10.199 + round_to_K(HeapRegionRemSet::static_mem_size()), 10.200 + round_to_K(HeapRegionRemSet::fl_mem_size())); 10.201 + 10.202 + out->print_cr(" "SIZE_FORMAT" occupied cards represented.", 10.203 + total_cards_occupied()); 10.204 + for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { 10.205 + (*current)->print_cards_occupied_info_on(out, total_cards_occupied()); 10.206 + } 10.207 + 10.208 + // Largest sized rem set region statistics 10.209 + HeapRegionRemSet* rem_set = max_rs_mem_sz_region()->rem_set(); 10.210 + out->print_cr(" Region with largest rem set = "HR_FORMAT", " 10.211 + "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.", 10.212 + HR_FORMAT_PARAMS(max_rs_mem_sz_region()), 10.213 + round_to_K(rem_set->mem_size()), 10.214 + round_to_K(rem_set->occupied())); 10.215 + 10.216 + // Strong code root statistics 10.217 + HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region()->rem_set(); 10.218 + out->print_cr(" Total heap region code root sets sizes = "SIZE_FORMAT"K." 10.219 + " Max = "SIZE_FORMAT"K.", 10.220 + round_to_K(total_code_root_mem_sz()), 10.221 + round_to_K(max_code_root_rem_set->strong_code_roots_mem_size())); 10.222 + for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { 10.223 + (*current)->print_code_root_mem_info_on(out, total_code_root_mem_sz()); 10.224 + } 10.225 + 10.226 + out->print_cr(" "SIZE_FORMAT" code roots represented.", 10.227 + total_code_root_elems()); 10.228 + for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { 10.229 + (*current)->print_code_root_elems_info_on(out, total_code_root_elems()); 10.230 + } 10.231 + 10.232 + out->print_cr(" Region with largest amount of code roots = "HR_FORMAT", " 10.233 + "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".", 10.234 + HR_FORMAT_PARAMS(max_code_root_mem_sz_region()), 10.235 + round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()), 10.236 + round_to_K(max_code_root_rem_set->strong_code_roots_list_length())); 10.237 + } 10.238 }; 10.239 10.240 -double calc_percentage(size_t numerator, size_t denominator) { 10.241 - if (denominator != 0) { 10.242 - return (double)numerator / denominator * 100.0; 10.243 - } else { 10.244 - return 0.0f; 10.245 - } 10.246 -} 10.247 - 10.248 void G1RemSetSummary::print_on(outputStream* out) { 10.249 - out->print_cr("\n Concurrent RS processed "SIZE_FORMAT" cards", 10.250 + out->print_cr("\n Recent concurrent refinement statistics"); 10.251 + out->print_cr(" Processed "SIZE_FORMAT" cards", 10.252 num_concurrent_refined_cards()); 10.253 out->print_cr(" Of %d completed buffers:", num_processed_buf_total()); 10.254 out->print_cr(" %8d (%5.1f%%) by concurrent RS threads.", 10.255 num_processed_buf_total(), 10.256 - calc_percentage(num_processed_buf_rs_threads(), num_processed_buf_total())); 10.257 + percent_of(num_processed_buf_rs_threads(), num_processed_buf_total())); 10.258 out->print_cr(" %8d (%5.1f%%) by mutator threads.", 10.259 num_processed_buf_mutator(), 10.260 - calc_percentage(num_processed_buf_mutator(), num_processed_buf_total())); 10.261 + percent_of(num_processed_buf_mutator(), num_processed_buf_total())); 10.262 + out->print_cr(" Did %d coarsenings.", num_coarsenings()); 10.263 out->print_cr(" Concurrent RS threads times (s)"); 10.264 out->print(" "); 10.265 for (uint i = 0; i < _num_vtimes; i++) { 10.266 @@ -207,33 +346,5 @@ 10.267 10.268 HRRSStatsIter blk; 10.269 G1CollectedHeap::heap()->heap_region_iterate(&blk); 10.270 - // RemSet stats 10.271 - out->print_cr(" Total heap region rem set sizes = "SIZE_FORMAT"K." 10.272 - " Max = "SIZE_FORMAT"K.", 10.273 - blk.total_rs_mem_sz()/K, blk.max_rs_mem_sz()/K); 10.274 - out->print_cr(" Static structures = "SIZE_FORMAT"K," 10.275 - " free_lists = "SIZE_FORMAT"K.", 10.276 - HeapRegionRemSet::static_mem_size() / K, 10.277 - HeapRegionRemSet::fl_mem_size() / K); 10.278 - out->print_cr(" "SIZE_FORMAT" occupied cards represented.", 10.279 - blk.occupied()); 10.280 - HeapRegion* max_rs_mem_sz_region = blk.max_rs_mem_sz_region(); 10.281 - HeapRegionRemSet* max_rs_rem_set = max_rs_mem_sz_region->rem_set(); 10.282 - out->print_cr(" Max size region = "HR_FORMAT", " 10.283 - "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.", 10.284 - HR_FORMAT_PARAMS(max_rs_mem_sz_region), 10.285 - (max_rs_rem_set->mem_size() + K - 1)/K, 10.286 - (max_rs_rem_set->occupied() + K - 1)/K); 10.287 - out->print_cr(" Did %d coarsenings.", num_coarsenings()); 10.288 - // Strong code root stats 10.289 - out->print_cr(" Total heap region code-root set sizes = "SIZE_FORMAT"K." 10.290 - " Max = "SIZE_FORMAT"K.", 10.291 - blk.total_code_root_mem_sz()/K, blk.max_code_root_mem_sz()/K); 10.292 - HeapRegion* max_code_root_mem_sz_region = blk.max_code_root_mem_sz_region(); 10.293 - HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region->rem_set(); 10.294 - out->print_cr(" Max size region = "HR_FORMAT", " 10.295 - "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".", 10.296 - HR_FORMAT_PARAMS(max_code_root_mem_sz_region), 10.297 - (max_code_root_rem_set->strong_code_roots_mem_size() + K - 1)/K, 10.298 - (max_code_root_rem_set->strong_code_roots_list_length())); 10.299 + blk.print_summary_on(out); 10.300 }
11.1 --- a/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp Thu Oct 03 10:35:32 2013 -0700 11.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp Fri Oct 04 13:37:25 2013 -0700 11.3 @@ -84,7 +84,7 @@ 11.4 void subtract_from(G1RemSetSummary* other); 11.5 11.6 // initialize and get the first sampling 11.7 - void initialize(G1RemSet* remset, uint num_workers); 11.8 + void initialize(G1RemSet* remset); 11.9 11.10 void print_on(outputStream* out); 11.11
12.1 --- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Thu Oct 03 10:35:32 2013 -0700 12.2 +++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Fri Oct 04 13:37:25 2013 -0700 12.3 @@ -64,6 +64,27 @@ 12.4 } 12.5 } 12.6 12.7 +bool G1SATBCardTableModRefBS::mark_card_deferred(size_t card_index) { 12.8 + jbyte val = _byte_map[card_index]; 12.9 + // It's already processed 12.10 + if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) { 12.11 + return false; 12.12 + } 12.13 + // Cached bit can be installed either on a clean card or on a claimed card. 12.14 + jbyte new_val = val; 12.15 + if (val == clean_card_val()) { 12.16 + new_val = (jbyte)deferred_card_val(); 12.17 + } else { 12.18 + if (val & claimed_card_val()) { 12.19 + new_val = val | (jbyte)deferred_card_val(); 12.20 + } 12.21 + } 12.22 + if (new_val != val) { 12.23 + Atomic::cmpxchg(new_val, &_byte_map[card_index], val); 12.24 + } 12.25 + return true; 12.26 +} 12.27 + 12.28 G1SATBCardTableLoggingModRefBS:: 12.29 G1SATBCardTableLoggingModRefBS(MemRegion whole_heap, 12.30 int max_covered_regions) :
13.1 --- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Thu Oct 03 10:35:32 2013 -0700 13.2 +++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Fri Oct 04 13:37:25 2013 -0700 13.3 @@ -89,6 +89,42 @@ 13.4 write_ref_array_pre_work(dst, count); 13.5 } 13.6 } 13.7 + 13.8 +/* 13.9 + Claimed and deferred bits are used together in G1 during the evacuation 13.10 + pause. These bits can have the following state transitions: 13.11 + 1. The claimed bit can be put over any other card state. Except that 13.12 + the "dirty -> dirty and claimed" transition is checked for in 13.13 + G1 code and is not used. 13.14 + 2. Deferred bit can be set only if the previous state of the card 13.15 + was either clean or claimed. mark_card_deferred() is wait-free. 13.16 + We do not care if the operation is be successful because if 13.17 + it does not it will only result in duplicate entry in the update 13.18 + buffer because of the "cache-miss". So it's not worth spinning. 13.19 + */ 13.20 + 13.21 + bool is_card_claimed(size_t card_index) { 13.22 + jbyte val = _byte_map[card_index]; 13.23 + return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val(); 13.24 + } 13.25 + 13.26 + void set_card_claimed(size_t card_index) { 13.27 + jbyte val = _byte_map[card_index]; 13.28 + if (val == clean_card_val()) { 13.29 + val = (jbyte)claimed_card_val(); 13.30 + } else { 13.31 + val |= (jbyte)claimed_card_val(); 13.32 + } 13.33 + _byte_map[card_index] = val; 13.34 + } 13.35 + 13.36 + bool mark_card_deferred(size_t card_index); 13.37 + 13.38 + bool is_card_deferred(size_t card_index) { 13.39 + jbyte val = _byte_map[card_index]; 13.40 + return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val(); 13.41 + } 13.42 + 13.43 }; 13.44 13.45 // Adds card-table logging to the post-barrier.
14.1 --- a/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp Thu Oct 03 10:35:32 2013 -0700 14.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp Fri Oct 04 13:37:25 2013 -0700 14.3 @@ -40,10 +40,8 @@ 14.4 14.5 void initialize_flags() { 14.6 // Do basic sizing work 14.7 - this->TwoGenerationCollectorPolicy::initialize_flags(); 14.8 + TwoGenerationCollectorPolicy::initialize_flags(); 14.9 14.10 - // If the user hasn't explicitly set the number of worker 14.11 - // threads, set the count. 14.12 assert(UseSerialGC || 14.13 !FLAG_IS_DEFAULT(ParallelGCThreads) || 14.14 (ParallelGCThreads > 0),
15.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp Thu Oct 03 10:35:32 2013 -0700 15.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp Fri Oct 04 13:37:25 2013 -0700 15.3 @@ -23,7 +23,6 @@ 15.4 */ 15.5 15.6 #include "precompiled.hpp" 15.7 -#include "gc_implementation/parallelScavenge/generationSizer.hpp" 15.8 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" 15.9 #include "gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp" 15.10 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
16.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp Thu Oct 03 10:35:32 2013 -0700 16.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp Fri Oct 04 13:37:25 2013 -0700 16.3 @@ -53,7 +53,6 @@ 16.4 16.5 // Forward decls 16.6 class elapsedTimer; 16.7 -class GenerationSizer; 16.8 16.9 class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { 16.10 friend class PSGCAdaptivePolicyCounters;
17.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Oct 03 10:35:32 2013 -0700 17.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Fri Oct 04 13:37:25 2013 -0700 17.3 @@ -26,7 +26,6 @@ 17.4 #include "classfile/symbolTable.hpp" 17.5 #include "classfile/systemDictionary.hpp" 17.6 #include "code/codeCache.hpp" 17.7 -#include "gc_implementation/parallelScavenge/generationSizer.hpp" 17.8 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" 17.9 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" 17.10 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
18.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Oct 03 10:35:32 2013 -0700 18.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Fri Oct 04 13:37:25 2013 -0700 18.3 @@ -27,7 +27,6 @@ 18.4 #include "classfile/systemDictionary.hpp" 18.5 #include "code/codeCache.hpp" 18.6 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" 18.7 -#include "gc_implementation/parallelScavenge/generationSizer.hpp" 18.8 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp" 18.9 #include "gc_implementation/parallelScavenge/pcTasks.hpp" 18.10 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
19.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Oct 03 10:35:32 2013 -0700 19.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Fri Oct 04 13:37:25 2013 -0700 19.3 @@ -27,7 +27,6 @@ 19.4 #include "code/codeCache.hpp" 19.5 #include "gc_implementation/parallelScavenge/cardTableExtension.hpp" 19.6 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" 19.7 -#include "gc_implementation/parallelScavenge/generationSizer.hpp" 19.8 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" 19.9 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" 19.10 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
20.1 --- a/src/share/vm/memory/cardTableModRefBS.cpp Thu Oct 03 10:35:32 2013 -0700 20.2 +++ b/src/share/vm/memory/cardTableModRefBS.cpp Fri Oct 04 13:37:25 2013 -0700 20.3 @@ -423,60 +423,6 @@ 20.4 inline_write_ref_field(field, newVal); 20.5 } 20.6 20.7 -/* 20.8 - Claimed and deferred bits are used together in G1 during the evacuation 20.9 - pause. These bits can have the following state transitions: 20.10 - 1. The claimed bit can be put over any other card state. Except that 20.11 - the "dirty -> dirty and claimed" transition is checked for in 20.12 - G1 code and is not used. 20.13 - 2. Deferred bit can be set only if the previous state of the card 20.14 - was either clean or claimed. mark_card_deferred() is wait-free. 20.15 - We do not care if the operation is be successful because if 20.16 - it does not it will only result in duplicate entry in the update 20.17 - buffer because of the "cache-miss". So it's not worth spinning. 20.18 - */ 20.19 - 20.20 - 20.21 -bool CardTableModRefBS::claim_card(size_t card_index) { 20.22 - jbyte val = _byte_map[card_index]; 20.23 - assert(val != dirty_card_val(), "Shouldn't claim a dirty card"); 20.24 - while (val == clean_card_val() || 20.25 - (val & (clean_card_mask_val() | claimed_card_val())) != claimed_card_val()) { 20.26 - jbyte new_val = val; 20.27 - if (val == clean_card_val()) { 20.28 - new_val = (jbyte)claimed_card_val(); 20.29 - } else { 20.30 - new_val = val | (jbyte)claimed_card_val(); 20.31 - } 20.32 - jbyte res = Atomic::cmpxchg(new_val, &_byte_map[card_index], val); 20.33 - if (res == val) { 20.34 - return true; 20.35 - } 20.36 - val = res; 20.37 - } 20.38 - return false; 20.39 -} 20.40 - 20.41 -bool CardTableModRefBS::mark_card_deferred(size_t card_index) { 20.42 - jbyte val = _byte_map[card_index]; 20.43 - // It's already processed 20.44 - if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) { 20.45 - return false; 20.46 - } 20.47 - // Cached bit can be installed either on a clean card or on a claimed card. 20.48 - jbyte new_val = val; 20.49 - if (val == clean_card_val()) { 20.50 - new_val = (jbyte)deferred_card_val(); 20.51 - } else { 20.52 - if (val & claimed_card_val()) { 20.53 - new_val = val | (jbyte)deferred_card_val(); 20.54 - } 20.55 - } 20.56 - if (new_val != val) { 20.57 - Atomic::cmpxchg(new_val, &_byte_map[card_index], val); 20.58 - } 20.59 - return true; 20.60 -} 20.61 20.62 void CardTableModRefBS::non_clean_card_iterate_possibly_parallel(Space* sp, 20.63 MemRegion mr,
21.1 --- a/src/share/vm/memory/cardTableModRefBS.hpp Thu Oct 03 10:35:32 2013 -0700 21.2 +++ b/src/share/vm/memory/cardTableModRefBS.hpp Fri Oct 04 13:37:25 2013 -0700 21.3 @@ -339,34 +339,10 @@ 21.4 _byte_map[card_index] = dirty_card_val(); 21.5 } 21.6 21.7 - bool is_card_claimed(size_t card_index) { 21.8 - jbyte val = _byte_map[card_index]; 21.9 - return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val(); 21.10 - } 21.11 - 21.12 - void set_card_claimed(size_t card_index) { 21.13 - jbyte val = _byte_map[card_index]; 21.14 - if (val == clean_card_val()) { 21.15 - val = (jbyte)claimed_card_val(); 21.16 - } else { 21.17 - val |= (jbyte)claimed_card_val(); 21.18 - } 21.19 - _byte_map[card_index] = val; 21.20 - } 21.21 - 21.22 - bool claim_card(size_t card_index); 21.23 - 21.24 bool is_card_clean(size_t card_index) { 21.25 return _byte_map[card_index] == clean_card_val(); 21.26 } 21.27 21.28 - bool is_card_deferred(size_t card_index) { 21.29 - jbyte val = _byte_map[card_index]; 21.30 - return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val(); 21.31 - } 21.32 - 21.33 - bool mark_card_deferred(size_t card_index); 21.34 - 21.35 // Card marking array base (adjusted for heap low boundary) 21.36 // This would be the 0th element of _byte_map, if the heap started at 0x0. 21.37 // But since the heap starts at some higher address, this points to somewhere
22.1 --- a/src/share/vm/memory/collectorPolicy.cpp Thu Oct 03 10:35:32 2013 -0700 22.2 +++ b/src/share/vm/memory/collectorPolicy.cpp Fri Oct 04 13:37:25 2013 -0700 22.3 @@ -64,19 +64,21 @@ 22.4 vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified"); 22.5 } 22.6 22.7 - if (!is_size_aligned(MaxMetaspaceSize, max_alignment())) { 22.8 - FLAG_SET_ERGO(uintx, MaxMetaspaceSize, 22.9 - restricted_align_down(MaxMetaspaceSize, max_alignment())); 22.10 + // Do not use FLAG_SET_ERGO to update MaxMetaspaceSize, since this will 22.11 + // override if MaxMetaspaceSize was set on the command line or not. 22.12 + // This information is needed later to conform to the specification of the 22.13 + // java.lang.management.MemoryUsage API. 22.14 + // 22.15 + // Ideally, we would be able to set the default value of MaxMetaspaceSize in 22.16 + // globals.hpp to the aligned value, but this is not possible, since the 22.17 + // alignment depends on other flags being parsed. 22.18 + MaxMetaspaceSize = restricted_align_down(MaxMetaspaceSize, max_alignment()); 22.19 + 22.20 + if (MetaspaceSize > MaxMetaspaceSize) { 22.21 + MetaspaceSize = MaxMetaspaceSize; 22.22 } 22.23 22.24 - if (MetaspaceSize > MaxMetaspaceSize) { 22.25 - FLAG_SET_ERGO(uintx, MetaspaceSize, MaxMetaspaceSize); 22.26 - } 22.27 - 22.28 - if (!is_size_aligned(MetaspaceSize, min_alignment())) { 22.29 - FLAG_SET_ERGO(uintx, MetaspaceSize, 22.30 - restricted_align_down(MetaspaceSize, min_alignment())); 22.31 - } 22.32 + MetaspaceSize = restricted_align_down(MetaspaceSize, min_alignment()); 22.33 22.34 assert(MetaspaceSize <= MaxMetaspaceSize, "Must be"); 22.35 22.36 @@ -135,15 +137,8 @@ 22.37 22.38 GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap, 22.39 int max_covered_regions) { 22.40 - switch (rem_set_name()) { 22.41 - case GenRemSet::CardTable: { 22.42 - CardTableRS* res = new CardTableRS(whole_heap, max_covered_regions); 22.43 - return res; 22.44 - } 22.45 - default: 22.46 - guarantee(false, "unrecognized GenRemSet::Name"); 22.47 - return NULL; 22.48 - } 22.49 + assert(rem_set_name() == GenRemSet::CardTable, "unrecognized GenRemSet::Name"); 22.50 + return new CardTableRS(whole_heap, max_covered_regions); 22.51 } 22.52 22.53 void CollectorPolicy::cleared_all_soft_refs() {
23.1 --- a/src/share/vm/memory/genRemSet.cpp Thu Oct 03 10:35:32 2013 -0700 23.2 +++ b/src/share/vm/memory/genRemSet.cpp Fri Oct 04 13:37:25 2013 -0700 23.3 @@ -32,13 +32,8 @@ 23.4 // enumeration.) 23.5 23.6 uintx GenRemSet::max_alignment_constraint(Name nm) { 23.7 - switch (nm) { 23.8 - case GenRemSet::CardTable: 23.9 - return CardTableRS::ct_max_alignment_constraint(); 23.10 - default: 23.11 - guarantee(false, "Unrecognized GenRemSet type."); 23.12 - return (0); // Make Windows compiler happy 23.13 - } 23.14 + assert(nm == GenRemSet::CardTable, "Unrecognized GenRemSet type."); 23.15 + return CardTableRS::ct_max_alignment_constraint(); 23.16 } 23.17 23.18 class HasAccumulatedModifiedOopsClosure : public KlassClosure {
24.1 --- a/src/share/vm/memory/metaspace.cpp Thu Oct 03 10:35:32 2013 -0700 24.2 +++ b/src/share/vm/memory/metaspace.cpp Fri Oct 04 13:37:25 2013 -0700 24.3 @@ -3104,7 +3104,7 @@ 24.4 MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) { 24.5 // DumpSharedSpaces doesn't use class metadata area (yet) 24.6 // Also, don't use class_vsm() unless UseCompressedClassPointers is true. 24.7 - if (mdtype == ClassType && using_class_space()) { 24.8 + if (is_class_space_allocation(mdtype)) { 24.9 return class_vsm()->allocate(word_size); 24.10 } else { 24.11 return vsm()->allocate(word_size); 24.12 @@ -3252,8 +3252,8 @@ 24.13 MetaspaceAux::dump(gclog_or_tty); 24.14 } 24.15 // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support 24.16 - const char* space_string = (mdtype == ClassType) ? "Compressed class space" : 24.17 - "Metadata space"; 24.18 + const char* space_string = is_class_space_allocation(mdtype) ? "Compressed class space" : 24.19 + "Metadata space"; 24.20 report_java_out_of_memory(space_string); 24.21 24.22 if (JvmtiExport::should_post_resource_exhausted()) { 24.23 @@ -3261,7 +3261,7 @@ 24.24 JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR, 24.25 space_string); 24.26 } 24.27 - if (mdtype == ClassType) { 24.28 + if (is_class_space_allocation(mdtype)) { 24.29 THROW_OOP_0(Universe::out_of_memory_error_class_metaspace()); 24.30 } else { 24.31 THROW_OOP_0(Universe::out_of_memory_error_metaspace());
25.1 --- a/src/share/vm/memory/metaspace.hpp Thu Oct 03 10:35:32 2013 -0700 25.2 +++ b/src/share/vm/memory/metaspace.hpp Fri Oct 04 13:37:25 2013 -0700 25.3 @@ -235,6 +235,9 @@ 25.4 return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces); 25.5 } 25.6 25.7 + static bool is_class_space_allocation(MetadataType mdType) { 25.8 + return mdType == ClassType && using_class_space(); 25.9 + } 25.10 }; 25.11 25.12 class MetaspaceAux : AllStatic {
26.1 --- a/test/gc/g1/TestSummarizeRSetStats.java Thu Oct 03 10:35:32 2013 -0700 26.2 +++ b/test/gc/g1/TestSummarizeRSetStats.java Fri Oct 04 13:37:25 2013 -0700 26.3 @@ -25,140 +25,61 @@ 26.4 * @test TestSummarizeRSetStats.java 26.5 * @bug 8013895 26.6 * @library /testlibrary 26.7 - * @build TestSummarizeRSetStats 26.8 + * @build TestSummarizeRSetStatsTools TestSummarizeRSetStats 26.9 * @summary Verify output of -XX:+G1SummarizeRSetStats 26.10 * @run main TestSummarizeRSetStats 26.11 * 26.12 * Test the output of G1SummarizeRSetStats in conjunction with G1SummarizeRSetStatsPeriod. 26.13 */ 26.14 26.15 -import com.oracle.java.testlibrary.*; 26.16 -import java.lang.Thread; 26.17 -import java.util.ArrayList; 26.18 -import java.util.Arrays; 26.19 - 26.20 -class RunSystemGCs { 26.21 - // 4M size, both are directly allocated into the old gen 26.22 - static Object[] largeObject1 = new Object[1024 * 1024]; 26.23 - static Object[] largeObject2 = new Object[1024 * 1024]; 26.24 - 26.25 - static int[] temp; 26.26 - 26.27 - public static void main(String[] args) { 26.28 - // create some cross-references between these objects 26.29 - for (int i = 0; i < largeObject1.length; i++) { 26.30 - largeObject1[i] = largeObject2; 26.31 - } 26.32 - 26.33 - for (int i = 0; i < largeObject2.length; i++) { 26.34 - largeObject2[i] = largeObject1; 26.35 - } 26.36 - 26.37 - int numGCs = Integer.parseInt(args[0]); 26.38 - 26.39 - if (numGCs > 0) { 26.40 - // try to force a minor collection: the young gen is 4M, the 26.41 - // amount of data allocated below is roughly that (4*1024*1024 + 26.42 - // some header data) 26.43 - for (int i = 0; i < 1024 ; i++) { 26.44 - temp = new int[1024]; 26.45 - } 26.46 - } 26.47 - 26.48 - for (int i = 0; i < numGCs - 1; i++) { 26.49 - System.gc(); 26.50 - } 26.51 - } 26.52 -} 26.53 - 26.54 public class TestSummarizeRSetStats { 26.55 26.56 - public static String runTest(String[] additionalArgs, int numGCs) throws Exception { 26.57 - ArrayList<String> finalargs = new ArrayList<String>(); 26.58 - String[] defaultArgs = new String[] { 26.59 - "-XX:+UseG1GC", 26.60 - "-Xmn4m", 26.61 - "-Xmx20m", 26.62 - "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking 26.63 - "-XX:+PrintGC", 26.64 - "-XX:+UnlockDiagnosticVMOptions", 26.65 - "-XX:G1HeapRegionSize=1M", 26.66 - }; 26.67 - 26.68 - finalargs.addAll(Arrays.asList(defaultArgs)); 26.69 - 26.70 - if (additionalArgs != null) { 26.71 - finalargs.addAll(Arrays.asList(additionalArgs)); 26.72 - } 26.73 - 26.74 - finalargs.add(RunSystemGCs.class.getName()); 26.75 - finalargs.add(String.valueOf(numGCs)); 26.76 - 26.77 - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 26.78 - finalargs.toArray(new String[0])); 26.79 - OutputAnalyzer output = new OutputAnalyzer(pb.start()); 26.80 - 26.81 - output.shouldHaveExitValue(0); 26.82 - 26.83 - String result = output.getStdout(); 26.84 - return result; 26.85 - } 26.86 - 26.87 - private static void expectStatistics(String result, int expectedCumulative, int expectedPeriodic) throws Exception { 26.88 - int actualTotal = result.split("Concurrent RS processed").length - 1; 26.89 - int actualCumulative = result.split("Cumulative RS summary").length - 1; 26.90 - 26.91 - if (expectedCumulative != actualCumulative) { 26.92 - throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative); 26.93 - } 26.94 - 26.95 - if (expectedPeriodic != (actualTotal - actualCumulative)) { 26.96 - throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative)); 26.97 - } 26.98 - } 26.99 - 26.100 public static void main(String[] args) throws Exception { 26.101 String result; 26.102 26.103 - // no RSet statistics output 26.104 - result = runTest(null, 0); 26.105 - expectStatistics(result, 0, 0); 26.106 + if (!TestSummarizeRSetStatsTools.testingG1GC()) { 26.107 + return; 26.108 + } 26.109 26.110 - // no RSet statistics output 26.111 - result = runTest(null, 2); 26.112 - expectStatistics(result, 0, 0); 26.113 + // no remembered set summary output 26.114 + result = TestSummarizeRSetStatsTools.runTest(null, 0); 26.115 + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0); 26.116 26.117 - // no RSet statistics output 26.118 - result = runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3); 26.119 - expectStatistics(result, 0, 0); 26.120 + // no remembered set summary output 26.121 + result = TestSummarizeRSetStatsTools.runTest(null, 2); 26.122 + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0); 26.123 26.124 - // single RSet statistics output at the end 26.125 - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0); 26.126 - expectStatistics(result, 1, 0); 26.127 + // no remembered set summary output 26.128 + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3); 26.129 + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0); 26.130 26.131 - // single RSet statistics output at the end 26.132 - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2); 26.133 - expectStatistics(result, 1, 0); 26.134 + // single remembered set summary output at the end 26.135 + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0); 26.136 + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0); 26.137 26.138 - // single RSet statistics output 26.139 - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0); 26.140 - expectStatistics(result, 1, 0); 26.141 + // single remembered set summary output at the end 26.142 + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2); 26.143 + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0); 26.144 26.145 - // two times RSet statistics output 26.146 - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1); 26.147 - expectStatistics(result, 1, 1); 26.148 + // single remembered set summary output 26.149 + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0); 26.150 + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0); 26.151 26.152 - // four times RSet statistics output 26.153 - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3); 26.154 - expectStatistics(result, 1, 3); 26.155 + // two times remembered set summary output 26.156 + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1); 26.157 + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2); 26.158 26.159 - // three times RSet statistics output 26.160 - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3); 26.161 - expectStatistics(result, 1, 2); 26.162 + // four times remembered set summary output 26.163 + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3); 26.164 + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 6); 26.165 26.166 - // single RSet statistics output 26.167 - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3); 26.168 - expectStatistics(result, 1, 1); 26.169 + // three times remembered set summary output 26.170 + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3); 26.171 + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 4); 26.172 + 26.173 + // single remembered set summary output 26.174 + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3); 26.175 + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2); 26.176 } 26.177 } 26.178
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/test/gc/g1/TestSummarizeRSetStatsPerRegion.java Fri Oct 04 13:37:25 2013 -0700 27.3 @@ -0,0 +1,55 @@ 27.4 +/* 27.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 27.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 27.7 + * 27.8 + * This code is free software; you can redistribute it and/or modify it 27.9 + * under the terms of the GNU General Public License version 2 only, as 27.10 + * published by the Free Software Foundation. 27.11 + * 27.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 27.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 27.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 27.15 + * version 2 for more details (a copy is included in the LICENSE file that 27.16 + * accompanied this code). 27.17 + * 27.18 + * You should have received a copy of the GNU General Public License version 27.19 + * 2 along with this work; if not, write to the Free Software Foundation, 27.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 27.21 + * 27.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 27.23 + * or visit www.oracle.com if you need additional information or have any 27.24 + * questions. 27.25 + */ 27.26 + 27.27 +/* 27.28 + * @test TestSummarizeRSetStatsPerRegion.java 27.29 + * @bug 8014078 27.30 + * @library /testlibrary 27.31 + * @build TestSummarizeRSetStatsTools TestSummarizeRSetStatsPerRegion 27.32 + * @summary Verify output of -XX:+G1SummarizeRSetStats in regards to per-region type output 27.33 + * @run main TestSummarizeRSetStatsPerRegion 27.34 + */ 27.35 + 27.36 +import com.oracle.java.testlibrary.*; 27.37 +import java.lang.Thread; 27.38 +import java.util.ArrayList; 27.39 +import java.util.Arrays; 27.40 + 27.41 +public class TestSummarizeRSetStatsPerRegion { 27.42 + 27.43 + public static void main(String[] args) throws Exception { 27.44 + String result; 27.45 + 27.46 + if (!TestSummarizeRSetStatsTools.testingG1GC()) { 27.47 + return; 27.48 + } 27.49 + 27.50 + // single remembered set summary output at the end 27.51 + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0); 27.52 + TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 0); 27.53 + 27.54 + // two times remembered set summary output 27.55 + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1); 27.56 + TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 2); 27.57 + } 27.58 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/test/gc/g1/TestSummarizeRSetStatsThreads.java Fri Oct 04 13:37:25 2013 -0700 28.3 @@ -0,0 +1,83 @@ 28.4 +/* 28.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 28.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 28.7 + * 28.8 + * This code is free software; you can redistribute it and/or modify it 28.9 + * under the terms of the GNU General Public License version 2 only, as 28.10 + * published by the Free Software Foundation. 28.11 + * 28.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 28.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 28.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 28.15 + * version 2 for more details (a copy is included in the LICENSE file that 28.16 + * accompanied this code). 28.17 + * 28.18 + * You should have received a copy of the GNU General Public License version 28.19 + * 2 along with this work; if not, write to the Free Software Foundation, 28.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 28.21 + * 28.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28.23 + * or visit www.oracle.com if you need additional information or have any 28.24 + * questions. 28.25 + */ 28.26 + 28.27 +/* 28.28 + * @test TestSummarizeRSetStatsThreads 28.29 + * @bug 8025441 28.30 + * @summary Ensure that various values of worker threads/concurrent 28.31 + * refinement threads do not crash the VM. 28.32 + * @key gc 28.33 + * @library /testlibrary 28.34 + */ 28.35 + 28.36 +import java.util.regex.Matcher; 28.37 +import java.util.regex.Pattern; 28.38 + 28.39 +import com.oracle.java.testlibrary.ProcessTools; 28.40 +import com.oracle.java.testlibrary.OutputAnalyzer; 28.41 + 28.42 +public class TestSummarizeRSetStatsThreads { 28.43 + 28.44 + private static void runTest(int refinementThreads, int workerThreads) throws Exception { 28.45 + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC", 28.46 + "-XX:+UnlockDiagnosticVMOptions", 28.47 + "-XX:+G1SummarizeRSetStats", 28.48 + "-XX:G1ConcRefinementThreads=" + refinementThreads, 28.49 + "-XX:ParallelGCThreads=" + workerThreads, 28.50 + "-version"); 28.51 + 28.52 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 28.53 + 28.54 + // check output to contain the string "Concurrent RS threads times (s)" followed by 28.55 + // the correct number of values in the next line. 28.56 + 28.57 + // a zero in refinement thread numbers indicates that the value in ParallelGCThreads should be used. 28.58 + // Additionally use at least one thread. 28.59 + int expectedNumRefinementThreads = refinementThreads == 0 ? workerThreads : refinementThreads; 28.60 + expectedNumRefinementThreads = Math.max(1, expectedNumRefinementThreads); 28.61 + // create the pattern made up of n copies of a floating point number pattern 28.62 + String numberPattern = String.format("%0" + expectedNumRefinementThreads + "d", 0) 28.63 + .replace("0", "\\s+\\d+\\.\\d+"); 28.64 + String pattern = "Concurrent RS threads times \\(s\\)$" + numberPattern + "$"; 28.65 + Matcher m = Pattern.compile(pattern, Pattern.MULTILINE).matcher(output.getStdout()); 28.66 + 28.67 + if (!m.find()) { 28.68 + throw new Exception("Could not find correct output for concurrent RS threads times in stdout," + 28.69 + " should match the pattern \"" + pattern + "\", but stdout is \n" + output.getStdout()); 28.70 + } 28.71 + output.shouldHaveExitValue(0); 28.72 + } 28.73 + 28.74 + public static void main(String[] args) throws Exception { 28.75 + if (!TestSummarizeRSetStatsTools.testingG1GC()) { 28.76 + return; 28.77 + } 28.78 + // different valid combinations of number of refinement and gc worker threads 28.79 + runTest(0, 0); 28.80 + runTest(0, 5); 28.81 + runTest(5, 0); 28.82 + runTest(10, 10); 28.83 + runTest(1, 2); 28.84 + runTest(4, 3); 28.85 + } 28.86 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/test/gc/g1/TestSummarizeRSetStatsTools.java Fri Oct 04 13:37:25 2013 -0700 29.3 @@ -0,0 +1,154 @@ 29.4 +/* 29.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 29.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 29.7 + * 29.8 + * This code is free software; you can redistribute it and/or modify it 29.9 + * under the terms of the GNU General Public License version 2 only, as 29.10 + * published by the Free Software Foundation. 29.11 + * 29.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 29.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 29.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 29.15 + * version 2 for more details (a copy is included in the LICENSE file that 29.16 + * accompanied this code). 29.17 + * 29.18 + * You should have received a copy of the GNU General Public License version 29.19 + * 2 along with this work; if not, write to the Free Software Foundation, 29.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 29.21 + * 29.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 29.23 + * or visit www.oracle.com if you need additional information or have any 29.24 + * questions. 29.25 + */ 29.26 + 29.27 +/* 29.28 + * Common helpers for TestSummarizeRSetStats* tests 29.29 + */ 29.30 + 29.31 +import sun.management.ManagementFactoryHelper; 29.32 +import com.sun.management.HotSpotDiagnosticMXBean; 29.33 +import com.sun.management.VMOption; 29.34 + 29.35 +import com.oracle.java.testlibrary.*; 29.36 +import java.util.regex.Matcher; 29.37 +import java.util.regex.Pattern; 29.38 +import java.lang.Thread; 29.39 +import java.util.ArrayList; 29.40 +import java.util.Arrays; 29.41 + 29.42 +class VerifySummaryOutput { 29.43 + // 4M size, both are directly allocated into the old gen 29.44 + static Object[] largeObject1 = new Object[1024 * 1024]; 29.45 + static Object[] largeObject2 = new Object[1024 * 1024]; 29.46 + 29.47 + static int[] temp; 29.48 + 29.49 + public static void main(String[] args) { 29.50 + // create some cross-references between these objects 29.51 + for (int i = 0; i < largeObject1.length; i++) { 29.52 + largeObject1[i] = largeObject2; 29.53 + } 29.54 + 29.55 + for (int i = 0; i < largeObject2.length; i++) { 29.56 + largeObject2[i] = largeObject1; 29.57 + } 29.58 + 29.59 + int numGCs = Integer.parseInt(args[0]); 29.60 + 29.61 + if (numGCs > 0) { 29.62 + // try to force a minor collection: the young gen is 4M, the 29.63 + // amount of data allocated below is roughly that (4*1024*1024 + 29.64 + // some header data) 29.65 + for (int i = 0; i < 1024 ; i++) { 29.66 + temp = new int[1024]; 29.67 + } 29.68 + } 29.69 + 29.70 + for (int i = 0; i < numGCs - 1; i++) { 29.71 + System.gc(); 29.72 + } 29.73 + } 29.74 +} 29.75 + 29.76 +public class TestSummarizeRSetStatsTools { 29.77 + 29.78 + // the VM is currently run using G1GC, i.e. trying to test G1 functionality. 29.79 + public static boolean testingG1GC() { 29.80 + HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); 29.81 + 29.82 + VMOption option = diagnostic.getVMOption("UseG1GC"); 29.83 + if (option.getValue().equals("false")) { 29.84 + System.out.println("Skipping this test. It is only a G1 test."); 29.85 + return false; 29.86 + } 29.87 + return true; 29.88 + } 29.89 + 29.90 + public static String runTest(String[] additionalArgs, int numGCs) throws Exception { 29.91 + ArrayList<String> finalargs = new ArrayList<String>(); 29.92 + String[] defaultArgs = new String[] { 29.93 + "-XX:+UseG1GC", 29.94 + "-XX:+UseCompressedOops", 29.95 + "-Xmn4m", 29.96 + "-Xmx20m", 29.97 + "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking 29.98 + "-XX:+PrintGC", 29.99 + "-XX:+UnlockDiagnosticVMOptions", 29.100 + "-XX:G1HeapRegionSize=1M", 29.101 + }; 29.102 + 29.103 + finalargs.addAll(Arrays.asList(defaultArgs)); 29.104 + 29.105 + if (additionalArgs != null) { 29.106 + finalargs.addAll(Arrays.asList(additionalArgs)); 29.107 + } 29.108 + 29.109 + finalargs.add(VerifySummaryOutput.class.getName()); 29.110 + finalargs.add(String.valueOf(numGCs)); 29.111 + 29.112 + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 29.113 + finalargs.toArray(new String[0])); 29.114 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 29.115 + 29.116 + output.shouldHaveExitValue(0); 29.117 + 29.118 + String result = output.getStdout(); 29.119 + return result; 29.120 + } 29.121 + 29.122 + private static void checkCounts(int expected, int actual, String which) throws Exception { 29.123 + if (expected != actual) { 29.124 + throw new Exception("RSet summaries mention " + which + " regions an incorrect number of times. Expected " + expected + ", got " + actual); 29.125 + } 29.126 + } 29.127 + 29.128 + public static void expectPerRegionRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception { 29.129 + expectRSetSummaries(result, expectedCumulative, expectedPeriodic); 29.130 + int actualYoung = result.split("Young regions").length - 1; 29.131 + int actualHumonguous = result.split("Humonguous regions").length - 1; 29.132 + int actualFree = result.split("Free regions").length - 1; 29.133 + int actualOther = result.split("Old regions").length - 1; 29.134 + 29.135 + // the strings we check for above are printed four times per summary 29.136 + int expectedPerRegionTypeInfo = (expectedCumulative + expectedPeriodic) * 4; 29.137 + 29.138 + checkCounts(expectedPerRegionTypeInfo, actualYoung, "Young"); 29.139 + checkCounts(expectedPerRegionTypeInfo, actualHumonguous, "Humonguous"); 29.140 + checkCounts(expectedPerRegionTypeInfo, actualFree, "Free"); 29.141 + checkCounts(expectedPerRegionTypeInfo, actualOther, "Old"); 29.142 + } 29.143 + 29.144 + public static void expectRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception { 29.145 + int actualTotal = result.split("concurrent refinement").length - 1; 29.146 + int actualCumulative = result.split("Cumulative RS summary").length - 1; 29.147 + 29.148 + if (expectedCumulative != actualCumulative) { 29.149 + throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative); 29.150 + } 29.151 + 29.152 + if (expectedPeriodic != (actualTotal - actualCumulative)) { 29.153 + throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative)); 29.154 + } 29.155 + } 29.156 +} 29.157 +
30.1 --- a/test/gc/metaspace/G1AddMetaspaceDependency.java Thu Oct 03 10:35:32 2013 -0700 30.2 +++ b/test/gc/metaspace/G1AddMetaspaceDependency.java Fri Oct 04 13:37:25 2013 -0700 30.3 @@ -107,7 +107,6 @@ 30.4 Loader f_loader = new Loader(b_name, b_bytes, a_name, a_loader); 30.5 Loader g_loader = new Loader(b_name, b_bytes, a_name, a_loader); 30.6 30.7 - byte[] b = new byte[20 * 2 << 20]; 30.8 Class<?> c; 30.9 c = b_loader.loadClass(b_name); 30.10 c = c_loader.loadClass(b_name);
31.1 --- a/test/gc/metaspace/TestPerfCountersAndMemoryPools.java Thu Oct 03 10:35:32 2013 -0700 31.2 +++ b/test/gc/metaspace/TestPerfCountersAndMemoryPools.java Fri Oct 04 13:37:25 2013 -0700 31.3 @@ -29,10 +29,11 @@ 31.4 31.5 /* @test TestPerfCountersAndMemoryPools 31.6 * @bug 8023476 31.7 + * @library /testlibrary 31.8 * @summary Tests that a MemoryPoolMXBeans and PerfCounters for metaspace 31.9 * report the same data. 31.10 - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools 31.11 - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools 31.12 + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData -Xint TestPerfCountersAndMemoryPools 31.13 + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData -Xint TestPerfCountersAndMemoryPools 31.14 */ 31.15 public class TestPerfCountersAndMemoryPools { 31.16 public static void main(String[] args) throws Exception { 31.17 @@ -43,11 +44,11 @@ 31.18 } 31.19 } 31.20 31.21 - private static MemoryUsage getMemoryUsage(String memoryPoolName) { 31.22 + private static MemoryPoolMXBean getMemoryPool(String memoryPoolName) { 31.23 List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans(); 31.24 for (MemoryPoolMXBean pool : pools) { 31.25 if (pool.getName().equals(memoryPoolName)) { 31.26 - return pool.getUsage(); 31.27 + return pool; 31.28 } 31.29 } 31.30 31.31 @@ -57,19 +58,18 @@ 31.32 31.33 private static void checkMemoryUsage(String memoryPoolName, String perfNS) 31.34 throws Exception { 31.35 - // Need to do a gc before each comparison to update the perf counters 31.36 + MemoryPoolMXBean pool = getMemoryPool(memoryPoolName); 31.37 31.38 + // Must do a GC to update performance counters 31.39 System.gc(); 31.40 - MemoryUsage mu = getMemoryUsage(memoryPoolName); 31.41 - assertEQ(getMinCapacity(perfNS), mu.getInit()); 31.42 + assertEQ(getMinCapacity(perfNS), pool.getUsage().getInit()); 31.43 31.44 + // Must do a second GC to update the perfomance counters again, since 31.45 + // the call pool.getUsage().getInit() could have allocated some 31.46 + // metadata. 31.47 System.gc(); 31.48 - mu = getMemoryUsage(memoryPoolName); 31.49 - assertEQ(getUsed(perfNS), mu.getUsed()); 31.50 - 31.51 - System.gc(); 31.52 - mu = getMemoryUsage(memoryPoolName); 31.53 - assertEQ(getCapacity(perfNS), mu.getCommitted()); 31.54 + assertEQ(getUsed(perfNS), pool.getUsage().getUsed()); 31.55 + assertEQ(getCapacity(perfNS), pool.getUsage().getCommitted()); 31.56 } 31.57 31.58 private static long getMinCapacity(String ns) throws Exception {