Übersicht der Quellen

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Impressum g1Allocator.cpp   Interaktion und
PortierbarkeitC

 

/*
 * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
  of the General  License  2only java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
 * published by the Free Software Foundation.
 *
 * This code assert(""SIZE_FORMAT" but    " at " PTR_FORMAT
 * ANY WARRANTY;                                                                               actual_word_size)
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
 * version 2 for more details     ;
 * accompanied this code).
 *
 *java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
  workif ,writeto   Software ,
 * Inc., 51 /java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
 *
 * Please contact Oracle, 500 Oracle Parkway,double  PadFactor  1.java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
 add_direct_allocated(plab_data-_direct_allocated)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
java.lang.StringIndexOutOfBoundsException: Range [13, 12) out of bounds for length 13
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
 */


#include "precompiled.hpp"
includeg1inline
#include "gc/g1/g1AllocRegion.inline.hpp"
#include "gc/g1/g1EvacInfo.hpp"_G1HeapRegionAttr:oung.,
#include "gc/g1/g1EvacStats.inline.hpp"                      java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "cg1g1NUMA.
#include "gc/g1/g1Policy.hpp"
#include "gc/_[1:Old.num_plab_fillsjava.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
#include "gc/g1/heapRegionSet.inline.hpp"
#include gc/."
#include "gc/shared/tlab_globals.hpp"
#include  G1PLABAllocator:waste)const{
#include "utilities/  result  ;

G1Allocator::G1Allocator(G1CollectedHeap* heap) :
  _g1h(heap),
  _numa(heap->numa()),
  _survivor_is_full(false),
  _  for (region_ state= ;state < G1HeapRegionAttr::Num state+){
  _num_alloc_regions(_numa->num_active_nodes()),
  _mutator_alloc_regions(NULL),
    for (  =0 < alloc_buffers_lengthstate) +){
  _old_gc_alloc_region(heap->alloc_buffer_stats(G1HeapRegionAttr::Old)),
ained_old_gc_alloc_regionNULL) {

  _mutator_alloc_regions       (buf! ){
  _survivor_gc_alloc_regions =  result=buf-waste(;
  G1EvacStats* stat = heap->alloc_buffer_stats(G1HeapRegionAttr::Young);

  for (uint i = 0; i <  }
    }
    ::new(_survivor_gc_alloc_regions   java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
  }
}

java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 0
  for (uint isize_tG1PLABAllocator:(1eapRegionAttr)  {
    _return _dest_data[which.type()]._cur_desired_plab_size;
    _survivor_gc_alloc_regions
  }
  FREE_C_HEAP_ARRAYjava.lang.StringIndexOutOfBoundsException: Range [7, 6) out of bounds for length 44
    for (region_type_ ;state Num +{
}

#ifdef ASSERT
bool=;node_indexalloc_buffers_lengthstate) node_index+java.lang.StringIndexOutOfBoundsException: Index 87 out of bounds for length 87
  uint node_index  ()java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
  return 
}
#endif

void G1Allocator::init_mutator_alloc_regions() {
  for (uint i = 0; i < _num_alloc_regions; i+
    assert(mutator_alloc_region(i)->get() ==  
    mutator_alloc_region(i return;
  }
}

void G1Allocator::release_mutator_alloc_regionsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
for( i=0 i  _um_alloc_regionsi+){
    mutator_alloc_region(i)->release();
    assert(mutator_alloc_region(i)->get() == NULL, "post-condition");
  }
}

bool G1Allocator::java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 1
  return _retained_old_gc_alloc_region G1ArchiveAllocator( java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
}

void G1Allocator::reuse_retained_old_region(  // and add it to our list of allocated regions. It is
                                            OldGCAllocRegion
                                             retained_old){
gion*retained_region =*etained_old;
  *retained_old = NULL;
  assert(retained_region     return false;
         "Archive  }

  // We will discard the current GC alloc region if:
   collection set (it can happen!),
  // b) it's already full (no point in using it),
  // c) it's empty (this means that it was emptied during
  // a cleanup and it should be on the free list now), or
  // d) it's humongous (this means that it was emptied
  // during a cleanup and was added to the free list, buts)
  // has been subsequently used to allocate a humongous
  // object that may be less than the region size).
  if (retained_region !=  ()alloc)
      !retained_region->_allocated_regions.appendjava.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
      !(->op)= ->()&
      !retained_region->is_empty() &&
      !retained_region->is_humongous()) {
    // The retained region was added to the old region set when it was
    // retired. We have to remove it now, since we don't allow regionsbottom hrb(;
/   to in   sets later 
    // it's retired again.
    _g1h->old_set_remove(retained_region);
    old->set(  // Since we've theset,call .
    _g1h-_1-monitoring_support-update_sizes;
    evacuation_info->return true
  }
}

void G1Allocator::init_gc_alloc_regions(G1EvacInfo* 
  assert_at_safepoint_on_vm_thread();

  _ = false;
  _old_is_full = false;

  i ;   + java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
    !alloc_new_region
  }

       ;
  reuse_retained_old_region(evacuation_info,
                            &_old_gc_alloc_region,
                              * =a-top)
}

void G1Allocator::release_gc_alloc_regions(G1EvacInfo* evacuation_info) {
  uint"  state:"PTR_FORMAT   ,
  for (uint node_index = 0; node_index <         (_ottom)p2i_-bottom))java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
survivor_region_count =survivor_gc_alloc_regionnode_indexcount)
    survivor_gc_alloc_region(node_index)->release();
  }
  evacuation_info->set_allocation_regions(survivor_region_count         _) allocation_region-end))java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
                                          old_gc_alloc_region()->count());

  // If we have an old GC alloc region to release, we'll save it in
  // _retained_old_gc_alloc_region. If we don't
  // _retained_old_gc_alloc_region will become NULL. This is what we
  // want either way so no reason to check explicitly for either
    // Try to allocate word_size in the current allocation chunk. Two cases
  _retained_old_gc_alloc_region = old_gc_alloc_region()
}

void G1Allocator::abandon_gc_alloc_regions() {
  for (inti =0 i <_num_alloc_regions;i+ java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
    assert(survivor_gc_alloc_region)-java.lang.StringIndexOutOfBoundsException: Range [72, 73) out of bounds for length 72
  }
  assert(old_gc_alloc_region   free_words (max old_top;
  _retained_old_gc_alloc_region = NULL;
}

bool G1Allocator::survivor_is_full() const {
  return _survivor_is_full;
}

 :old_is_full) {
  return _old_is_full;
}

void G1Allocator::set_survivor_full() {
   
}

void G1Allocator::set_old_full() {
  _old_is_full = true;
}

size_t:(){
  // Return the remaining space in the cur alloc region, but not less than
        :(,fill_sizejava.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58

  // Also, this value can be at most the humongous object threshold,
  // since we can't allow tlabs to grow big enough to accommodate
  // humongous objects.

  uint node_index = current_node_index();
  HeapRegion hr=mutator_alloc_region(node_index-get;
  size_t max_tlab = _g1h->max_tlab_size() * wordSize;
  if (hr == NULL) {
    return max_tlab;
    java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
    return clamp(hr->free(), MinTLABSizejava.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 31
  }
}

size_t G1Allocator::used_in_alloc_regions() {
assert(eap_lock>( =NULL,Sbeownedonthisthreadbehalf.)java.lang.StringIndexOutOfBoundsException: Index 81 out of bounds for length 81
  size_t used = 0;
  for (uint i = 0; i < _num_alloc_regions; i++)  return NULLjava.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
    used =mutator_alloc_region)>sed_in_alloc_regions;
  }
  return used;
}


java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
                                              
                                              uint node_index) {
  size_t temp"large,);
  HeapWord* result = par_allocate_during_gc(dest, word_size, assertiend_alignment_in_bytes ,
  assert(result == NULL || temp == word_size,
         "         "alignmentSIZE_FORMAT"not %) aligned", end_alignment_in_bytes;
         word_size, temp, p2i(result));
  return result;
}

HeapWord* G1Allocator::}
                                              size_t min_word_size,
                                               ,
                                              size_t*   if (nd_alignment_in_bytes! 0 {
                                              uint node_indexe*  currtopjava.lang.StringIndexOutOfBoundsException: Range [65, 63) out of bounds for length 65
  switch (dest/  therequiredis than we canrepresent
    case G1HeapRegionAttr::Young:
      return survivor_attempt_allocation(min_word_size, desired_word_size, actual_word_size, node_index);
    case G1HeapRegionAttr::Old:
      return old_attempt_allocationmin_word_size desired_word_size,)java.lang.StringIndexOutOfBoundsException: Index 88 out of bounds for length 88
    default:
      ShouldNotReachHere();
      return NULL; // Keep some compilers happy
  }
}

                          java.lang.StringIndexOutOfBoundsException: Range [49, 48) out of bounds for length 50
       size_t desired_word_size,
                                                   size_t* actual_word_size,
                                                   uint node_index) {
  assert(!_g1h->is_humongous(desired_word_size  =archive_mem_allocate);
         "we should not be ith_objects(fill, fill_size);

  HeapWord* result = java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 5
                                                                              
                                                                              actual_word_size);
  if (result ==   /the    .  
    MutexLocker x(FreeList_lock,/java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
   java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 95
    // actually is still memory available. Redo the check under the lock to avoid unnecessary work;_.at(index)= allocation_regionjava.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
    // the memory may have been used up as the threads waited to acquire the lock.
    if (!survivor_is_full()) {
      result(node_indexattempt_allocation_lockedjava.lang.StringIndexOutOfBoundsException: Index 93 out of bounds for length 93
                                                                              
                                                                              actual_word_size
      -((java.lang.StringIndexOutOfBoundsException: Range [45, 43) out of bounds for length 80
          java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 18
      }
    }
  }
  ifassert=base_address"- ,address   base_address)java.lang.StringIndexOutOfBoundsException: Index 90 out of bounds for length 90
    _g1h->dirty_young_block(result, *actual_word_size);
  }
  return result;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

HeapWord* G1Allocator::old_attempt_allocation(size_t min_word_size,
                                              size_t desired_word_size,
                                              size_t* actual_word_size) {
  assert(!_g1h->is_humongous(desired_word_size),
         "we should not be seeing humongous-size allocations in this path");

  HeapWord* result = old_gc_alloc_region()->attempt_allocation(min_word_size,
                                                               desired_word_size,
                                                               actual_word_size);
  if (result == NULL && !old_is_full()) {
    MutexLocker x(FreeList_lock, Mutex::_no_safepoint_check_flag);
    // Multiple threads may have queued at the FreeList_lock above after checking whether there
    // actually is still memory available. Redo the check under the lock to avoid unnecessary work;
    // the memory may have been used up as the threads waited to acquire the lock.
    if (!old_is_full()) {
      result = old_gc_alloc_region()->attempt_allocation_locked(min_word_size,
                                                                desired_word_size,
                                                                actual_word_size);
      if (result == NULL) {
        set_old_full();
      }
    }
  }
  return result;
}

G1PLABAllocator::PLABData::PLABData() :
  _alloc_buffer(nullptr),
  _direct_allocated(0),
  _num_plab_fills(0),
  _num_direct_allocations(0),
  _plab_fill_counter(0),
  _cur_desired_plab_size(0),
  _num_alloc_buffers(0) { }

G1PLABAllocator::PLABData::~PLABData() {
  if (_alloc_buffer == nullptr) {
    return;
  }
  for (uint node_index = 0; node_index < _num_alloc_buffers; node_index++) {
    delete _alloc_buffer[node_index];
  }
  FREE_C_HEAP_ARRAY(PLAB*, _alloc_buffer);
}

void G1PLABAllocator::PLABData::initialize(uint num_alloc_buffers, size_t desired_plab_size, size_t tolerated_refills) {
  _num_alloc_buffers = num_alloc_buffers;
  _alloc_buffer = NEW_C_HEAP_ARRAY(PLAB*, _num_alloc_buffers, mtGC);

  for (uint node_index = 0; node_index < _num_alloc_buffers; node_index++) {
    _alloc_buffer[node_index] = new PLAB(desired_plab_size);
  }

  _plab_fill_counter = tolerated_refills;
  _cur_desired_plab_size = desired_plab_size;
}

void G1PLABAllocator::PLABData::notify_plab_refill(size_t tolerated_refills, size_t next_plab_size) {
  _num_plab_fills++;
  if (should_boost()) {
    _plab_fill_counter = tolerated_refills;
    _cur_desired_plab_size = next_plab_size;
  } else {
    _plab_fill_counter--;
  }
}

G1PLABAllocator::G1PLABAllocator(G1Allocator* allocator) :
  _g1h(G1CollectedHeap::heap()),
  _allocator(allocator) {

  if (ResizePLAB) {
    // See G1EvacStats::compute_desired_plab_sz for the reasoning why this is the
    // expected number of refills.
    double const ExpectedNumberOfRefills = G1LastPLABAverageOccupancy / TargetPLABWastePct;
    // Add some padding to the threshold to not boost exactly when the targeted refills
    // were reached.
    // E.g. due to limitation of PLAB size to non-humongous objects and region boundaries
    // a thread may experience more refills than expected. Keeping the PLAB waste low
    // is the main goal, so being a bit conservative is better.
    double const PadFactor = 1.5;
    _tolerated_refills = MAX2(ExpectedNumberOfRefills, 1.0) * PadFactor;
  } else {
    // Make the tolerated refills a huge number.
    _tolerated_refills = SIZE_MAX;
  }
  // The initial PLAB refill should not count, hence the +1 for the first boost.
  size_t initial_tolerated_refills = ResizePLAB ? _tolerated_refills + 1 : _tolerated_refills;
  for (region_type_t state = 0; state < G1HeapRegionAttr::Num; state++) {
    _dest_data[state].initialize(alloc_buffers_length(state), _g1h->desired_plab_sz(state), initial_tolerated_refills);
  }
}

bool G1PLABAllocator::may_throw_away_buffer(size_t const allocation_word_sz, size_t const buffer_size) const {
  return (allocation_word_sz * 100 < buffer_size * ParallelGCBufferWastePct);
}

HeapWord* G1PLABAllocator::allocate_direct_or_new_plab(G1HeapRegionAttr dest,
                                                       size_t word_sz,
                                                       bool* plab_refill_failed,
                                                       uint node_index) {
  size_t plab_word_size = plab_size(dest.type());
  size_t next_plab_word_size = plab_word_size;

  PLABData* plab_data = &_dest_data[dest.type()];

  if (plab_data->should_boost()) {
    next_plab_word_size = _g1h->clamp_plab_size(next_plab_word_size * 2);
  }

  size_t required_in_plab = PLAB::size_required_for_allocation(word_sz);

  // Only get a new PLAB if the allocation fits into the to-be-allocated PLAB and
  // it would not waste more than ParallelGCBufferWastePct in the current PLAB.
  // Boosting the PLAB also increasingly allows more waste to occur.
  if ((required_in_plab <= next_plab_word_size) &&
    may_throw_away_buffer(required_in_plab, plab_word_size)) {

    PLAB* alloc_buf = alloc_buffer(dest, node_index);
    guarantee(alloc_buf->words_remaining() <= required_in_plab, "must be");

    alloc_buf->retire();

    plab_data->notify_plab_refill(_tolerated_refills, next_plab_word_size);
    plab_word_size = next_plab_word_size;

    size_t actual_plab_size = 0;
    HeapWord* buf = _allocator->par_allocate_during_gc(dest,
                                                       required_in_plab,
                                                       plab_word_size,
                                                       &actual_plab_size,
                                                       node_index);

    assert(buf == NULL || ((actual_plab_size >= required_in_plab) && (actual_plab_size <= plab_word_size)),
           "Requested at minimum %zu, desired %zu words, but got %zu at " PTR_FORMAT,
           required_in_plab, plab_word_size, actual_plab_size, p2i(buf));

    if (buf != NULL) {
      alloc_buf->set_buf(buf, actual_plab_size);

      HeapWord* const obj = alloc_buf->allocate(word_sz);
      assert(obj != NULL, "PLAB should have been big enough, tried to allocate "
                          "%zu requiring %zu PLAB size %zu",
                          word_sz, required_in_plab, plab_word_size);
      return obj;
    }
    // Otherwise.
    *plab_refill_failed = true;
  }
  // Try direct allocation.
  HeapWord* result = _allocator->par_allocate_during_gc(dest, word_sz, node_index);
  if (result != NULL) {
    plab_data->_direct_allocated += word_sz;
    plab_data->_num_direct_allocations++;
  }
  return result;
}

void G1PLABAllocator::undo_allocation(G1HeapRegionAttr dest, HeapWord* obj, size_t word_sz, uint node_index) {
  alloc_buffer(dest, node_index)->undo_allocation(obj, word_sz);
}

void G1PLABAllocator::flush_and_retire_stats(uint num_workers) {
  for (region_type_t state = 0; state < G1HeapRegionAttr::Num; state++) {
    G1EvacStats* stats = _g1h->alloc_buffer_stats(state);
    for (uint node_index = 0; node_index < alloc_buffers_length(state); node_index++) {
      PLAB* const buf = alloc_buffer(state, node_index);
      if (buf != NULL) {
        buf->flush_and_retire_stats(stats);
      }
    }
    PLABData* plab_data = &_dest_data[state];
    stats->add_num_plab_filled(plab_data->_num_plab_fills);
    stats->add_direct_allocated(plab_data->_direct_allocated);
    stats->add_num_direct_allocated(plab_data->_num_direct_allocations);
  }

  log_trace(gc, plab)("PLAB boost: Young %zu -> %zu refills %zu (tolerated %zu) Old %zu -> %zu refills %zu (tolerated %zu)",
                      _g1h->alloc_buffer_stats(G1HeapRegionAttr::Young)->desired_plab_size(num_workers),
                      plab_size(G1HeapRegionAttr::Young),
                      _dest_data[G1HeapRegionAttr::Young]._num_plab_fills,
                      _tolerated_refills,
                      _g1h->alloc_buffer_stats(G1HeapRegionAttr::Old)->desired_plab_size(num_workers),
                      plab_size(G1HeapRegionAttr::Old),
                      _dest_data[G1HeapRegionAttr::Old]._num_plab_fills,
                      _tolerated_refills);
}

size_t G1PLABAllocator::waste() const {
  size_t result = 0;
  for (region_type_t state = 0; state < G1HeapRegionAttr::Num; state++) {
    for (uint node_index = 0; node_index < alloc_buffers_length(state); node_index++) {
      PLAB* const buf = alloc_buffer(state, node_index);
      if (buf != NULL) {
        result += buf->waste();
      }
    }
  }
  return result;
}

size_t G1PLABAllocator::plab_size(G1HeapRegionAttr which) const {
  return _dest_data[which.type()]._cur_desired_plab_size;
}

size_t G1PLABAllocator::undo_waste() const {
  size_t result = 0;
  for (region_type_t state = 0; state < G1HeapRegionAttr::Num; state++) {
    for (uint node_index = 0; node_index < alloc_buffers_length(state); node_index++) {
      PLAB* const buf = alloc_buffer(state, node_index);
      if (buf != NULL) {
        result += buf->undo_waste();
      }
    }
  }
  return result;
}

G1ArchiveAllocator* G1ArchiveAllocator::create_allocator(G1CollectedHeap* g1h, bool open) {
  return new G1ArchiveAllocator(g1h, open);
}

bool G1ArchiveAllocator::alloc_new_region() {
  // Allocate the highest free region in the reserved heap,
  // and add it to our list of allocated regions. It is marked
  // archive and added to the old set.
  HeapRegion* hr = _g1h->alloc_highest_free_region();
  if (hr == NULL) {
    return false;
  }
  assert(hr->is_empty(), "expected empty region (index %u)", hr->hrm_index());
  if (_open) {
    hr->set_open_archive();
  } else {
    hr->set_closed_archive();
  }
  _g1h->policy()->remset_tracker()->update_at_allocate(hr);
  _g1h->archive_set_add(hr);
  _g1h->hr_printer()->alloc(hr);
  _allocated_regions.append(hr);
  _allocation_region = hr;

  // Set up _bottom and _max to begin allocating in the lowest
  // min_region_size'd chunk of the allocated G1 region.
  _bottom = hr->bottom();
  _max = _bottom + HeapRegion::min_region_size_in_words();

  // Since we've modified the old set, call update_sizes.
  _g1h->monitoring_support()->update_sizes();
  return true;
}

HeapWord* G1ArchiveAllocator::archive_mem_allocate(size_t word_size) {
  assert(word_size != 0, "size must not be zero");
  if (_allocation_region == NULL) {
    if (!alloc_new_region()) {
      return NULL;
    }
  }
  HeapWord* old_top = _allocation_region->top();
  assert(_bottom >= _allocation_region->bottom(),
         "inconsistent allocation state: " PTR_FORMAT " < " PTR_FORMAT,
         p2i(_bottom), p2i(_allocation_region->bottom()));
  assert(_max <= _allocation_region->end(),
         "inconsistent allocation state: " PTR_FORMAT " > " PTR_FORMAT,
         p2i(_max), p2i(_allocation_region->end()));
  assert(_bottom <= old_top && old_top <= _max,
         "inconsistent allocation state: expected "
         PTR_FORMAT " <= " PTR_FORMAT " <= " PTR_FORMAT,
         p2i(_bottom), p2i(old_top), p2i(_max));

  // Try to allocate word_size in the current allocation chunk. Two cases
  // require special treatment:
  // 1. no enough space for word_size
  // 2. after allocating word_size, there's non-zero space left, but too small for the minimal filler
  // In both cases, we retire the current chunk and move on to the next one.
  size_t free_words = pointer_delta(_max, old_top);
  if (free_words < word_size ||
      ((free_words - word_size != 0) && (free_words - word_size < CollectedHeap::min_fill_size()))) {
    // Retiring the current chunk
    if (old_top != _max) {
      // Non-zero space; need to insert the filler
      size_t fill_size = free_words;
      CollectedHeap::fill_with_object(old_top, fill_size);
    }
    // Set the current chunk as "full"
    _allocation_region->set_top(_max);

    // Check if we've just used up the last min_region_size'd chunk
    // in the current region, and if so, allocate a new one.
    if (_max != _allocation_region->end()) {
      // Shift to the next chunk
      old_top = _bottom = _max;
      _max = _bottom + HeapRegion::min_region_size_in_words();
    } else {
      if (!alloc_new_region()) {
        return NULL;
      }
      old_top = _allocation_region->bottom();
    }
  }
  assert(pointer_delta(_max, old_top) >= word_size, "enough space left");
  _allocation_region->set_top(old_top + word_size);

  return old_top;
}

void G1ArchiveAllocator::complete_archive(GrowableArray<MemRegion>* ranges,
                                          size_t end_alignment_in_bytes) {
  assert((end_alignment_in_bytes >> LogHeapWordSize) < HeapRegion::min_region_size_in_words(),
         "alignment " SIZE_FORMAT " too large", end_alignment_in_bytes);
  assert(is_aligned(end_alignment_in_bytes, HeapWordSize),
         "alignment " SIZE_FORMAT " is not HeapWord (%u) aligned", end_alignment_in_bytes, HeapWordSize);

  // If we've allocated nothing, simply return.
  if (_allocation_region == NULL) {
    return;
  }

  // If an end alignment was requested, insert filler objects.
  if (end_alignment_in_bytes != 0) {
    HeapWord* currtop = _allocation_region->top();
    HeapWord* newtop = align_up(currtop, end_alignment_in_bytes);
    size_t fill_size = pointer_delta(newtop, currtop);
    if (fill_size != 0) {
      if (fill_size < CollectedHeap::min_fill_size()) {
        // If the required fill is smaller than we can represent,
        // bump up to the next aligned address. We know we won't exceed the current
        // region boundary because the max supported alignment is smaller than the min
        // region size, and because the allocation code never leaves space smaller than
        // the min_fill_size at the top of the current allocation region.
        newtop = align_up(currtop + CollectedHeap::min_fill_size(),
                          end_alignment_in_bytes);
        fill_size = pointer_delta(newtop, currtop);
      }
      HeapWord* fill = archive_mem_allocate(fill_size);
      CollectedHeap::fill_with_objects(fill, fill_size);
    }
  }

  // Loop through the allocated regions, and create MemRegions summarizing
  // the allocated address range, combining contiguous ranges. Add the
  // MemRegions to the GrowableArray provided by the caller.
  int index = _allocated_regions.length() - 1;
  assert(_allocated_regions.at(index) == _allocation_region,
         "expected region %u at end of array, found %u",
         _allocation_region->hrm_index(), _allocated_regions.at(index)->hrm_index());
  HeapWord* base_address = _allocation_region->bottom();
  HeapWord* top = base_address;

  while (index >= 0) {
    HeapRegion* next = _allocated_regions.at(index);
    HeapWord* new_base = next->bottom();
    HeapWord* new_top = next->top();
    if (new_base != top) {
      ranges->append(MemRegion(base_address, pointer_delta(top, base_address)));
      base_address = new_base;
    }
    top = new_top;
    index = index - 1;
  }

  assert(top != base_address, "zero-sized range, address " PTR_FORMAT, p2i(base_address));
  ranges->append(MemRegion(base_address, pointer_delta(top, base_address)));
  _allocated_regions.clear();
  _allocation_region = NULL;
};

Messung V0.5 in Prozent
C=93 H=92 G=92

¤ Dauer der Verarbeitung: 0.17 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

letze Version des Elbe Quellennavigators


Jenseits des Üblichen ....

Besucher

Besucher

Statistik
#Sources=1127926
#Domains=2039723