hotspot/src/share/vm/gc/g1/g1Allocator.cpp
changeset 32377 5ee15c417d02
parent 32193 862a68285b1e
child 32379 aa14adafaf0f
equal deleted inserted replaced
32376:b5e8340b77cb 32377:5ee15c417d02
    77 }
    77 }
    78 
    78 
    79 void G1DefaultAllocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) {
    79 void G1DefaultAllocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) {
    80   assert_at_safepoint(true /* should_be_vm_thread */);
    80   assert_at_safepoint(true /* should_be_vm_thread */);
    81 
    81 
       
    82   G1Allocator::init_gc_alloc_regions(evacuation_info);
       
    83 
    82   _survivor_gc_alloc_region.init();
    84   _survivor_gc_alloc_region.init();
    83   _old_gc_alloc_region.init();
    85   _old_gc_alloc_region.init();
    84   reuse_retained_old_region(evacuation_info,
    86   reuse_retained_old_region(evacuation_info,
    85                             &_old_gc_alloc_region,
    87                             &_old_gc_alloc_region,
    86                             &_retained_old_gc_alloc_region);
    88                             &_retained_old_gc_alloc_region);
   145       ShouldNotReachHere();
   147       ShouldNotReachHere();
   146       return NULL; // Keep some compilers happy
   148       return NULL; // Keep some compilers happy
   147   }
   149   }
   148 }
   150 }
   149 
   151 
       
   152 bool G1Allocator::survivor_is_full(AllocationContext_t context) const {
       
   153   return _survivor_is_full;
       
   154 }
       
   155 
       
   156 bool G1Allocator::old_is_full(AllocationContext_t context) const {
       
   157   return _old_is_full;
       
   158 }
       
   159 
       
   160 void G1Allocator::set_survivor_full(AllocationContext_t context) {
       
   161   _survivor_is_full = true;
       
   162 }
       
   163 
       
   164 void G1Allocator::set_old_full(AllocationContext_t context) {
       
   165   _old_is_full = true;
       
   166 }
       
   167 
   150 HeapWord* G1Allocator::survivor_attempt_allocation(size_t word_size,
   168 HeapWord* G1Allocator::survivor_attempt_allocation(size_t word_size,
   151                                                    AllocationContext_t context) {
   169                                                    AllocationContext_t context) {
   152   assert(!_g1h->is_humongous(word_size),
   170   assert(!_g1h->is_humongous(word_size),
   153          "we should not be seeing humongous-size allocations in this path");
   171          "we should not be seeing humongous-size allocations in this path");
   154 
   172 
   155   HeapWord* result = survivor_gc_alloc_region(context)->attempt_allocation(word_size,
   173   HeapWord* result = survivor_gc_alloc_region(context)->attempt_allocation(word_size,
   156                                                                            false /* bot_updates */);
   174                                                                            false /* bot_updates */);
   157   if (result == NULL) {
   175   if (result == NULL && !survivor_is_full(context)) {
   158     MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
   176     MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
   159     result = survivor_gc_alloc_region(context)->attempt_allocation_locked(word_size,
   177     result = survivor_gc_alloc_region(context)->attempt_allocation_locked(word_size,
   160                                                                           false /* bot_updates */);
   178                                                                           false /* bot_updates */);
       
   179     if (result == NULL) {
       
   180       set_survivor_full(context);
       
   181     }
   161   }
   182   }
   162   if (result != NULL) {
   183   if (result != NULL) {
   163     _g1h->dirty_young_block(result, word_size);
   184     _g1h->dirty_young_block(result, word_size);
   164   }
   185   }
   165   return result;
   186   return result;
   170   assert(!_g1h->is_humongous(word_size),
   191   assert(!_g1h->is_humongous(word_size),
   171          "we should not be seeing humongous-size allocations in this path");
   192          "we should not be seeing humongous-size allocations in this path");
   172 
   193 
   173   HeapWord* result = old_gc_alloc_region(context)->attempt_allocation(word_size,
   194   HeapWord* result = old_gc_alloc_region(context)->attempt_allocation(word_size,
   174                                                                       true /* bot_updates */);
   195                                                                       true /* bot_updates */);
   175   if (result == NULL) {
   196   if (result == NULL && !old_is_full(context)) {
   176     MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
   197     MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
   177     result = old_gc_alloc_region(context)->attempt_allocation_locked(word_size,
   198     result = old_gc_alloc_region(context)->attempt_allocation_locked(word_size,
   178                                                                      true /* bot_updates */);
   199                                                                      true /* bot_updates */);
       
   200     if (result == NULL) {
       
   201       set_old_full(context);
       
   202     }
   179   }
   203   }
   180   return result;
   204   return result;
       
   205 }
       
   206 
       
   207 void G1Allocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) {
       
   208   _survivor_is_full = false;
       
   209   _old_is_full = false;
   181 }
   210 }
   182 
   211 
   183 G1PLABAllocator::G1PLABAllocator(G1Allocator* allocator) :
   212 G1PLABAllocator::G1PLABAllocator(G1Allocator* allocator) :
   184   _g1h(G1CollectedHeap::heap()),
   213   _g1h(G1CollectedHeap::heap()),
   185   _allocator(allocator),
   214   _allocator(allocator),
   186   _survivor_alignment_bytes(calc_survivor_alignment_bytes()) {
   215   _survivor_alignment_bytes(calc_survivor_alignment_bytes()) {
   187 }
   216 }
   188 
   217 
   189 HeapWord* G1PLABAllocator::allocate_direct_or_new_plab(InCSetState dest,
   218 HeapWord* G1PLABAllocator::allocate_direct_or_new_plab(InCSetState dest,
   190                                                        size_t word_sz,
   219                                                        size_t word_sz,
   191                                                        AllocationContext_t context) {
   220                                                        AllocationContext_t context,
       
   221                                                        bool* plab_refill_failed) {
   192   size_t gclab_word_size = _g1h->desired_plab_sz(dest);
   222   size_t gclab_word_size = _g1h->desired_plab_sz(dest);
   193   if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
   223   if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
   194     G1PLAB* alloc_buf = alloc_buffer(dest, context);
   224     G1PLAB* alloc_buf = alloc_buffer(dest, context);
   195     alloc_buf->retire();
   225     alloc_buf->retire();
   196 
   226 
   197     HeapWord* buf = _allocator->par_allocate_during_gc(dest, gclab_word_size, context);
   227     HeapWord* buf = _allocator->par_allocate_during_gc(dest, gclab_word_size, context);
   198     if (buf == NULL) {
   228     if (buf != NULL) {
   199       return NULL; // Let caller handle allocation failure.
   229       // Otherwise.
       
   230       alloc_buf->set_word_size(gclab_word_size);
       
   231       alloc_buf->set_buf(buf);
       
   232 
       
   233       HeapWord* const obj = alloc_buf->allocate(word_sz);
       
   234       assert(obj != NULL, "buffer was definitely big enough...");
       
   235       return obj;
   200     }
   236     }
   201     // Otherwise.
   237     // Otherwise.
   202     alloc_buf->set_word_size(gclab_word_size);
   238     *plab_refill_failed = true;
   203     alloc_buf->set_buf(buf);
   239   }
   204 
   240   // Try inline allocation.
   205     HeapWord* const obj = alloc_buf->allocate(word_sz);
   241   return _allocator->par_allocate_during_gc(dest, word_sz, context);
   206     assert(obj != NULL, "buffer was definitely big enough...");
       
   207     return obj;
       
   208   } else {
       
   209     return _allocator->par_allocate_during_gc(dest, word_sz, context);
       
   210   }
       
   211 }
   242 }
   212 
   243 
   213 void G1PLABAllocator::undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context) {
   244 void G1PLABAllocator::undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context) {
   214   alloc_buffer(dest, context)->undo_allocation(obj, word_sz);
   245   alloc_buffer(dest, context)->undo_allocation(obj, word_sz);
   215 }
   246 }