1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue May 28 09:32:06 2013 +0200 1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Mon Jun 03 14:37:13 2013 -0700 1.3 @@ -593,11 +593,6 @@ 1.4 // may not be a humongous - it must fit into a single heap region. 1.5 HeapWord* par_allocate_during_gc(GCAllocPurpose purpose, size_t word_size); 1.6 1.7 - HeapWord* allocate_during_gc_slow(GCAllocPurpose purpose, 1.8 - HeapRegion* alloc_region, 1.9 - bool par, 1.10 - size_t word_size); 1.11 - 1.12 // Ensure that no further allocations can happen in "r", bearing in mind 1.13 // that parallel threads might be attempting allocations. 1.14 void par_allocate_remaining_space(HeapRegion* r); 1.15 @@ -1733,6 +1728,95 @@ 1.16 ParGCAllocBuffer::retire(end_of_gc, retain); 1.17 _retired = true; 1.18 } 1.19 + 1.20 + bool is_retired() { 1.21 + return _retired; 1.22 + } 1.23 +}; 1.24 + 1.25 +class G1ParGCAllocBufferContainer { 1.26 +protected: 1.27 + static int const _priority_max = 2; 1.28 + G1ParGCAllocBuffer* _priority_buffer[_priority_max]; 1.29 + 1.30 +public: 1.31 + G1ParGCAllocBufferContainer(size_t gclab_word_size) { 1.32 + for (int pr = 0; pr < _priority_max; ++pr) { 1.33 + _priority_buffer[pr] = new G1ParGCAllocBuffer(gclab_word_size); 1.34 + } 1.35 + } 1.36 + 1.37 + ~G1ParGCAllocBufferContainer() { 1.38 + for (int pr = 0; pr < _priority_max; ++pr) { 1.39 + assert(_priority_buffer[pr]->is_retired(), "alloc buffers should all retire at this point."); 1.40 + delete _priority_buffer[pr]; 1.41 + } 1.42 + } 1.43 + 1.44 + HeapWord* allocate(size_t word_sz) { 1.45 + HeapWord* obj; 1.46 + for (int pr = 0; pr < _priority_max; ++pr) { 1.47 + obj = _priority_buffer[pr]->allocate(word_sz); 1.48 + if (obj != NULL) return obj; 1.49 + } 1.50 + return obj; 1.51 + } 1.52 + 1.53 + bool contains(void* addr) { 1.54 + for (int pr = 0; pr < _priority_max; ++pr) { 1.55 + if (_priority_buffer[pr]->contains(addr)) return true; 1.56 + } 1.57 + return false; 1.58 + } 1.59 + 1.60 + void undo_allocation(HeapWord* obj, size_t word_sz) { 1.61 + bool finish_undo; 1.62 + for (int pr = 0; pr < _priority_max; ++pr) { 1.63 + if (_priority_buffer[pr]->contains(obj)) { 1.64 + _priority_buffer[pr]->undo_allocation(obj, word_sz); 1.65 + finish_undo = true; 1.66 + } 1.67 + } 1.68 + if (!finish_undo) ShouldNotReachHere(); 1.69 + } 1.70 + 1.71 + size_t words_remaining() { 1.72 + size_t result = 0; 1.73 + for (int pr = 0; pr < _priority_max; ++pr) { 1.74 + result += _priority_buffer[pr]->words_remaining(); 1.75 + } 1.76 + return result; 1.77 + } 1.78 + 1.79 + size_t words_remaining_in_retired_buffer() { 1.80 + G1ParGCAllocBuffer* retired = _priority_buffer[0]; 1.81 + return retired->words_remaining(); 1.82 + } 1.83 + 1.84 + void flush_stats_and_retire(PLABStats* stats, bool end_of_gc, bool retain) { 1.85 + for (int pr = 0; pr < _priority_max; ++pr) { 1.86 + _priority_buffer[pr]->flush_stats_and_retire(stats, end_of_gc, retain); 1.87 + } 1.88 + } 1.89 + 1.90 + void update(bool end_of_gc, bool retain, HeapWord* buf, size_t word_sz) { 1.91 + G1ParGCAllocBuffer* retired_and_set = _priority_buffer[0]; 1.92 + retired_and_set->retire(end_of_gc, retain); 1.93 + retired_and_set->set_buf(buf); 1.94 + retired_and_set->set_word_size(word_sz); 1.95 + adjust_priority_order(); 1.96 + } 1.97 + 1.98 +private: 1.99 + void adjust_priority_order() { 1.100 + G1ParGCAllocBuffer* retired_and_set = _priority_buffer[0]; 1.101 + 1.102 + int last = _priority_max - 1; 1.103 + for (int pr = 0; pr < last; ++pr) { 1.104 + _priority_buffer[pr] = _priority_buffer[pr + 1]; 1.105 + } 1.106 + _priority_buffer[last] = retired_and_set; 1.107 + } 1.108 }; 1.109 1.110 class G1ParScanThreadState : public StackObj { 1.111 @@ -1743,9 +1827,9 @@ 1.112 CardTableModRefBS* _ct_bs; 1.113 G1RemSet* _g1_rem; 1.114 1.115 - G1ParGCAllocBuffer _surviving_alloc_buffer; 1.116 - G1ParGCAllocBuffer _tenured_alloc_buffer; 1.117 - G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount]; 1.118 + G1ParGCAllocBufferContainer _surviving_alloc_buffer; 1.119 + G1ParGCAllocBufferContainer _tenured_alloc_buffer; 1.120 + G1ParGCAllocBufferContainer* _alloc_buffers[GCAllocPurposeCount]; 1.121 ageTable _age_table; 1.122 1.123 size_t _alloc_buffer_waste; 1.124 @@ -1809,7 +1893,7 @@ 1.125 RefToScanQueue* refs() { return _refs; } 1.126 ageTable* age_table() { return &_age_table; } 1.127 1.128 - G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose) { 1.129 + G1ParGCAllocBufferContainer* alloc_buffer(GCAllocPurpose purpose) { 1.130 return _alloc_buffers[purpose]; 1.131 } 1.132 1.133 @@ -1839,15 +1923,13 @@ 1.134 HeapWord* obj = NULL; 1.135 size_t gclab_word_size = _g1h->desired_plab_sz(purpose); 1.136 if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) { 1.137 - G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose); 1.138 - add_to_alloc_buffer_waste(alloc_buf->words_remaining()); 1.139 - alloc_buf->retire(false /* end_of_gc */, false /* retain */); 1.140 + G1ParGCAllocBufferContainer* alloc_buf = alloc_buffer(purpose); 1.141 1.142 HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size); 1.143 if (buf == NULL) return NULL; // Let caller handle allocation failure. 1.144 - // Otherwise. 1.145 - alloc_buf->set_word_size(gclab_word_size); 1.146 - alloc_buf->set_buf(buf); 1.147 + 1.148 + add_to_alloc_buffer_waste(alloc_buf->words_remaining_in_retired_buffer()); 1.149 + alloc_buf->update(false /* end_of_gc */, false /* retain */, buf, gclab_word_size); 1.150 1.151 obj = alloc_buf->allocate(word_sz); 1.152 assert(obj != NULL, "buffer was definitely big enough..."); 1.153 @@ -1959,7 +2041,6 @@ 1.154 } 1.155 } 1.156 1.157 -public: 1.158 void trim_queue(); 1.159 }; 1.160