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

Print this page

        

@@ -588,15 +588,10 @@
   // allocation region, either by picking one or expanding the
   // heap, and then allocate a block of the given size. The block
   // may not be a humongous - it must fit into a single heap region.
   HeapWord* par_allocate_during_gc(GCAllocPurpose purpose, size_t word_size);
 
-  HeapWord* allocate_during_gc_slow(GCAllocPurpose purpose,
-                                    HeapRegion*    alloc_region,
-                                    bool           par,
-                                    size_t         word_size);
-
   // Ensure that no further allocations can happen in "r", bearing in mind
   // that parallel threads might be attempting allocations.
   void par_allocate_remaining_space(HeapRegion* r);
 
   // Allocation attempt during GC for a survivor object / PLAB.

@@ -1744,20 +1739,29 @@
     _retired = true;
   }
 };
 
 class G1ParScanThreadState : public StackObj {
+private:
+  enum GCAllocPriority {
+    GCAllocPriority1,
+    GCAllocPriority2,
+    GCAllocPriorityCount
+  };
+
+  int buf_idx(int purpose, int priority) {
+    return purpose*GCAllocPriorityCount + priority;
+  }
+
 protected:
   G1CollectedHeap* _g1h;
   RefToScanQueue*  _refs;
   DirtyCardQueue   _dcq;
   CardTableModRefBS* _ct_bs;
   G1RemSet* _g1_rem;
 
-  G1ParGCAllocBuffer  _surviving_alloc_buffer;
-  G1ParGCAllocBuffer  _tenured_alloc_buffer;
-  G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount];
+  G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount*GCAllocPriorityCount];
   ageTable            _age_table;
 
   size_t           _alloc_buffer_waste;
   size_t           _undo_waste;
 

@@ -1812,17 +1816,21 @@
 public:
   G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num);
 
   ~G1ParScanThreadState() {
     FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC);
+    for (int ap = 0; ap < GCAllocPurposeCount; ++ap)
+      for (int pr = 0; pr < GCAllocPriorityCount; ++pr) {
+        delete alloc_buffer(GCAllocPurpose(ap), GCAllocPriority(pr));
+      }
   }
 
   RefToScanQueue*   refs()            { return _refs;             }
   ageTable*         age_table()       { return &_age_table;       }
 
-  G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose) {
-    return _alloc_buffers[purpose];
+  G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose, GCAllocPriority priority) {
+    return _alloc_buffers[buf_idx(purpose, priority)];
   }
 
   size_t alloc_buffer_waste() const              { return _alloc_buffer_waste; }
   size_t undo_waste() const                      { return _undo_waste; }
 

@@ -1847,44 +1855,57 @@
 
   HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) {
     HeapWord* obj = NULL;
     size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
     if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
-      G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose);
-      add_to_alloc_buffer_waste(alloc_buf->words_remaining());
-      alloc_buf->retire(false /* end_of_gc */, false /* retain */);
+      G1ParGCAllocBuffer* alloc_buf1 = alloc_buffer(purpose, GCAllocPriority1);
+      G1ParGCAllocBuffer* alloc_buf2 = alloc_buffer(purpose, GCAllocPriority2);
+
+      add_to_alloc_buffer_waste(alloc_buf1->words_remaining());
+      alloc_buf1->retire(false /* end_of_gc */, false /* retain */);
 
       HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size);
       if (buf == NULL) return NULL; // Let caller handle allocation failure.
       // Otherwise.
-      alloc_buf->set_word_size(gclab_word_size);
-      alloc_buf->set_buf(buf);
+      alloc_buf1->set_word_size(gclab_word_size);
+      alloc_buf1->set_buf(buf);
 
-      obj = alloc_buf->allocate(word_sz);
+      obj = alloc_buf1->allocate(word_sz);
       assert(obj != NULL, "buffer was definitely big enough...");
+
+      // Swap buffers in order to preserve the priority order
+      _alloc_buffers[buf_idx(purpose, GCAllocPriority1)] = alloc_buf2;
+      _alloc_buffers[buf_idx(purpose, GCAllocPriority2)] = alloc_buf1;
     } else {
       obj = _g1h->par_allocate_during_gc(purpose, word_sz);
     }
     return obj;
   }
 
   HeapWord* allocate(GCAllocPurpose purpose, size_t word_sz) {
-    HeapWord* obj = alloc_buffer(purpose)->allocate(word_sz);
+    HeapWord* obj;
+    for (int pr = 0; pr < GCAllocPriorityCount; ++pr) {
+      obj = alloc_buffer(purpose, (GCAllocPriority)pr)->allocate(word_sz);
     if (obj != NULL) return obj;
+    }
+    // Otherwise.
     return allocate_slow(purpose, word_sz);
   }
 
   void undo_allocation(GCAllocPurpose purpose, HeapWord* obj, size_t word_sz) {
-    if (alloc_buffer(purpose)->contains(obj)) {
-      assert(alloc_buffer(purpose)->contains(obj + word_sz - 1),
+    for (int pr = 0; pr < GCAllocPriorityCount; ++pr) {
+      if (alloc_buffer(purpose, (GCAllocPriority)pr)->contains(obj)) {
+        assert(alloc_buffer(purpose, pr)->contains(obj + word_sz - 1),
              "should contain whole object");
-      alloc_buffer(purpose)->undo_allocation(obj, word_sz);
-    } else {
+        alloc_buffer(purpose, (GCAllocPriority)pr)->undo_allocation(obj, word_sz);
+        return;
+      }
+    }
+
       CollectedHeap::fill_with_object(obj, word_sz);
       add_to_undo_waste(word_sz);
     }
-  }
 
   void set_evac_failure_closure(OopsInHeapRegionClosure* evac_failure_cl) {
     _evac_failure_cl = evac_failure_cl;
   }
   OopsInHeapRegionClosure* evac_failure_closure() {

@@ -1936,14 +1957,16 @@
     // age -1 regions (i.e. non-young ones)
     return _surviving_young_words;
   }
 
   void retire_alloc_buffers() {
-    for (int ap = 0; ap < GCAllocPurposeCount; ++ap) {
-      size_t waste = _alloc_buffers[ap]->words_remaining();
+    for (int ap = 0; ap < GCAllocPurposeCount; ++ap)
+      for (int pr = 0; pr < GCAllocPriorityCount; ++pr) {
+        G1ParGCAllocBuffer* buffer = alloc_buffer((GCAllocPurpose)ap, (GCAllocPriority)pr);
+        size_t waste = buffer->words_remaining();
       add_to_alloc_buffer_waste(waste);
-      _alloc_buffers[ap]->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap),
+        buffer->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap),
                                                  true /* end_of_gc */,
                                                  false /* retain */);
     }
   }
 

@@ -1967,10 +1990,9 @@
     } else {
       deal_with_reference((oop*)ref);
     }
   }
 
-public:
   void trim_queue();
 };
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP