src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp

changeset 5206
87c64c0438fb
parent 5159
001ec9515f84
child 5237
f2110083203d
     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  

mercurial