< prev index next >

src/share/vm/gc/g1/g1Allocator.hpp

Print this page
rev 8789 : [mq]: 8073052-Rename-and-clean-up-the-allocation-manager-hierarchy-in-g1Allocator
rev 8790 : imported patch 8003237-no-wait-for-free-list
rev 8791 : imported patch jon-fast-evac-failure


  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_GC_G1_G1ALLOCATOR_HPP
  26 #define SHARE_VM_GC_G1_G1ALLOCATOR_HPP
  27 
  28 #include "gc/g1/g1AllocRegion.hpp"
  29 #include "gc/g1/g1AllocationContext.hpp"
  30 #include "gc/g1/g1InCSetState.hpp"
  31 #include "gc/shared/collectedHeap.hpp"
  32 #include "gc/shared/plab.hpp"
  33 
  34 class EvacuationInfo;
  35 
  36 // Interface to keep track of which regions G1 is currently allocating into. Provides
  37 // some accessors (e.g. allocating into them, or getting their occupancy).
  38 // Also keeps track of retained regions across GCs.
  39 class G1Allocator : public CHeapObj<mtGC> {
  40   friend class VMStructs;



  41 protected:
  42   G1CollectedHeap* _g1h;
  43 
  44   virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) = 0;
  45 






  46   // Accessors to the allocation regions.
  47   virtual SurvivorGCAllocRegion* survivor_gc_alloc_region(AllocationContext_t context) = 0;
  48   virtual OldGCAllocRegion* old_gc_alloc_region(AllocationContext_t context) = 0;
  49 
  50   // Allocation attempt during GC for a survivor object / PLAB.
  51   inline HeapWord* survivor_attempt_allocation(size_t word_size,
  52                                                AllocationContext_t context);
  53   // Allocation attempt during GC for an old object / PLAB.
  54   inline HeapWord* old_attempt_allocation(size_t word_size,
  55                                           AllocationContext_t context);
  56 public:
  57   G1Allocator(G1CollectedHeap* heap) : _g1h(heap) { }
  58   virtual ~G1Allocator() { }
  59 
  60   static G1Allocator* create_allocator(G1CollectedHeap* g1h);
  61 
  62 #ifdef ASSERT
  63   // Do we currently have an active mutator region to allocate into?
  64   bool has_mutator_alloc_region(AllocationContext_t context) { return mutator_alloc_region(context)->get() != NULL; }
  65 #endif
  66   virtual void init_mutator_alloc_region() = 0;
  67   virtual void release_mutator_alloc_region() = 0;
  68 
  69   virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
  70   virtual void release_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
  71   virtual void abandon_gc_alloc_regions() = 0;
  72 
  73   // Management of retained regions.
  74 
  75   virtual bool is_retained_old_region(HeapRegion* hr) = 0;
  76   void reuse_retained_old_region(EvacuationInfo& evacuation_info,
  77                                  OldGCAllocRegion* old,
  78                                  HeapRegion** retained);
  79  
  80   // Allocate blocks of memory during mutator time.
  81 
  82   inline HeapWord* attempt_allocation(size_t word_size, AllocationContext_t context);
  83   inline HeapWord* attempt_allocation_locked(size_t word_size, AllocationContext_t context);
  84   inline HeapWord* attempt_allocation_force(size_t word_size, AllocationContext_t context);
  85 
  86   size_t unsafe_max_tlab_alloc(AllocationContext_t context);
  87   
  88   // Allocate blocks of memory during garbage collection. Will ensure an
  89   // allocation region, either by picking one or expanding the


 206   static uint calc_survivor_alignment_bytes() {
 207     assert(SurvivorAlignmentInBytes >= ObjectAlignmentInBytes, "sanity");
 208     if (SurvivorAlignmentInBytes == ObjectAlignmentInBytes) {
 209       // No need to align objects in the survivors differently, return 0
 210       // which means "survivor alignment is not used".
 211       return 0;
 212     } else {
 213       assert(SurvivorAlignmentInBytes > 0, "sanity");
 214       return SurvivorAlignmentInBytes;
 215     }
 216   }
 217 
 218 public:
 219   G1PLABAllocator(G1Allocator* allocator);
 220   virtual ~G1PLABAllocator() { }
 221 
 222   static G1PLABAllocator* create_allocator(G1Allocator* allocator);
 223 
 224   virtual void waste(size_t& wasted, size_t& undo_wasted) = 0;
 225 
 226   // Allocate word_sz words in dest, either directly into the regions or by
 227   // allocating a new PLAB. Returns the address of the allocated memory, NULL if
 228   // not successful.
 229   HeapWord* allocate_direct_or_new_plab(InCSetState dest,

 230                                         size_t word_sz,
 231                                         AllocationContext_t context);

 232 
 233   // Allocate word_sz words in the PLAB of dest.  Returns the address of the
 234   // allocated memory, NULL if not successful.
 235   HeapWord* plab_allocate(InCSetState dest,
 236                           size_t word_sz,
 237                           AllocationContext_t context) {
 238     G1PLAB* buffer = alloc_buffer(dest, context);
 239     if (_survivor_alignment_bytes == 0 || !dest.is_young()) {
 240       return buffer->allocate(word_sz);
 241     } else {
 242       return buffer->allocate_aligned(word_sz, _survivor_alignment_bytes);
 243     }
 244   }
 245 
 246   HeapWord* allocate(InCSetState dest, size_t word_sz,
 247                      AllocationContext_t context) {


 248     HeapWord* const obj = plab_allocate(dest, word_sz, context);
 249     if (obj != NULL) {
 250       return obj;
 251     }
 252     return allocate_direct_or_new_plab(dest, word_sz, context);
 253   }
 254 
 255   void undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context);
 256 };
 257 
 258 // The default PLAB allocator for G1. Keeps the current (single) PLAB for survivor
 259 // and old generation allocation.
 260 class G1DefaultPLABAllocator : public G1PLABAllocator {
 261   G1PLAB  _surviving_alloc_buffer;
 262   G1PLAB  _tenured_alloc_buffer;
 263   G1PLAB* _alloc_buffers[InCSetState::Num];
 264 
 265 public:
 266   G1DefaultPLABAllocator(G1Allocator* _allocator);
 267 
 268   virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) {
 269     assert(dest.is_valid(),
 270            err_msg("Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value()));
 271     assert(_alloc_buffers[dest.value()] != NULL,
 272            err_msg("Allocation buffer is NULL: " CSETSTATE_FORMAT, dest.value()));




  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_GC_G1_G1ALLOCATOR_HPP
  26 #define SHARE_VM_GC_G1_G1ALLOCATOR_HPP
  27 
  28 #include "gc/g1/g1AllocRegion.hpp"
  29 #include "gc/g1/g1AllocationContext.hpp"
  30 #include "gc/g1/g1InCSetState.hpp"
  31 #include "gc/shared/collectedHeap.hpp"
  32 #include "gc/shared/plab.hpp"
  33 
  34 class EvacuationInfo;
  35 
  36 // Interface to keep track of which regions G1 is currently allocating into. Provides
  37 // some accessors (e.g. allocating into them, or getting their occupancy).
  38 // Also keeps track of retained regions across GCs.
  39 class G1Allocator : public CHeapObj<mtGC> {
  40   friend class VMStructs;
  41 private:
  42   bool _survivor_is_full;
  43   bool _old_is_full;
  44 protected:
  45   G1CollectedHeap* _g1h;
  46 
  47   virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) = 0;
  48 
  49   virtual bool survivor_is_full(AllocationContext_t context) const;
  50   virtual bool old_is_full(AllocationContext_t context) const;
  51 
  52   virtual void set_survivor_full(AllocationContext_t context);
  53   virtual void set_old_full(AllocationContext_t context);
  54   
  55   // Accessors to the allocation regions.
  56   virtual SurvivorGCAllocRegion* survivor_gc_alloc_region(AllocationContext_t context) = 0;
  57   virtual OldGCAllocRegion* old_gc_alloc_region(AllocationContext_t context) = 0;
  58 
  59   // Allocation attempt during GC for a survivor object / PLAB.
  60   inline HeapWord* survivor_attempt_allocation(size_t word_size,
  61                                                AllocationContext_t context);
  62   // Allocation attempt during GC for an old object / PLAB.
  63   inline HeapWord* old_attempt_allocation(size_t word_size,
  64                                           AllocationContext_t context);
  65 public:
  66   G1Allocator(G1CollectedHeap* heap) : _g1h(heap), _survivor_is_full(false), _old_is_full(false) { }
  67   virtual ~G1Allocator() { }
  68 
  69   static G1Allocator* create_allocator(G1CollectedHeap* g1h);
  70 
  71 #ifdef ASSERT
  72   // Do we currently have an active mutator region to allocate into?
  73   bool has_mutator_alloc_region(AllocationContext_t context) { return mutator_alloc_region(context)->get() != NULL; }
  74 #endif
  75   virtual void init_mutator_alloc_region() = 0;
  76   virtual void release_mutator_alloc_region() = 0;
  77 
  78   virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info);
  79   virtual void release_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
  80   virtual void abandon_gc_alloc_regions() = 0;
  81 
  82   // Management of retained regions.
  83 
  84   virtual bool is_retained_old_region(HeapRegion* hr) = 0;
  85   void reuse_retained_old_region(EvacuationInfo& evacuation_info,
  86                                  OldGCAllocRegion* old,
  87                                  HeapRegion** retained);
  88  
  89   // Allocate blocks of memory during mutator time.
  90 
  91   inline HeapWord* attempt_allocation(size_t word_size, AllocationContext_t context);
  92   inline HeapWord* attempt_allocation_locked(size_t word_size, AllocationContext_t context);
  93   inline HeapWord* attempt_allocation_force(size_t word_size, AllocationContext_t context);
  94 
  95   size_t unsafe_max_tlab_alloc(AllocationContext_t context);
  96   
  97   // Allocate blocks of memory during garbage collection. Will ensure an
  98   // allocation region, either by picking one or expanding the


 215   static uint calc_survivor_alignment_bytes() {
 216     assert(SurvivorAlignmentInBytes >= ObjectAlignmentInBytes, "sanity");
 217     if (SurvivorAlignmentInBytes == ObjectAlignmentInBytes) {
 218       // No need to align objects in the survivors differently, return 0
 219       // which means "survivor alignment is not used".
 220       return 0;
 221     } else {
 222       assert(SurvivorAlignmentInBytes > 0, "sanity");
 223       return SurvivorAlignmentInBytes;
 224     }
 225   }
 226 
 227 public:
 228   G1PLABAllocator(G1Allocator* allocator);
 229   virtual ~G1PLABAllocator() { }
 230 
 231   static G1PLABAllocator* create_allocator(G1Allocator* allocator);
 232 
 233   virtual void waste(size_t& wasted, size_t& undo_wasted) = 0;
 234 
 235   // Allocate word_sz words in dest, either directly into the regions (inline) or by
 236   // allocating a new PLAB. Returns the address of the allocated memory, NULL if
 237   // not successful. Plab_refill_failed indicates whether an attempt to refill the
 238   // PLAB failed or not.
 239   HeapWord* allocate_inline_or_new_plab(InCSetState dest,
 240                                         size_t word_sz,
 241                                         AllocationContext_t context,
 242                                         bool* plab_refill_failed);
 243 
 244   // Allocate word_sz words in the PLAB of dest.  Returns the address of the
 245   // allocated memory, NULL if not successful.
 246   HeapWord* plab_allocate(InCSetState dest,
 247                           size_t word_sz,
 248                           AllocationContext_t context) {
 249     G1PLAB* buffer = alloc_buffer(dest, context);
 250     if (_survivor_alignment_bytes == 0 || !dest.is_young()) {
 251       return buffer->allocate(word_sz);
 252     } else {
 253       return buffer->allocate_aligned(word_sz, _survivor_alignment_bytes);
 254     }
 255   }
 256 
 257   HeapWord* allocate(InCSetState dest,
 258                      size_t word_sz,
 259                      AllocationContext_t context,
 260                      bool* refill_failed) {
 261     HeapWord* const obj = plab_allocate(dest, word_sz, context);
 262     if (obj != NULL) {
 263       return obj;
 264     }
 265     return allocate_inline_or_new_plab(dest, word_sz, context, refill_failed);
 266   }
 267 
 268   void undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context);
 269 };
 270 
 271 // The default PLAB allocator for G1. Keeps the current (single) PLAB for survivor
 272 // and old generation allocation.
 273 class G1DefaultPLABAllocator : public G1PLABAllocator {
 274   G1PLAB  _surviving_alloc_buffer;
 275   G1PLAB  _tenured_alloc_buffer;
 276   G1PLAB* _alloc_buffers[InCSetState::Num];
 277 
 278 public:
 279   G1DefaultPLABAllocator(G1Allocator* _allocator);
 280 
 281   virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) {
 282     assert(dest.is_valid(),
 283            err_msg("Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value()));
 284     assert(_alloc_buffers[dest.value()] != NULL,
 285            err_msg("Allocation buffer is NULL: " CSETSTATE_FORMAT, dest.value()));


< prev index next >