src/hotspot/share/gc/g1/g1ParScanThreadState.cpp
changeset 57802 854e828d6b5b
parent 57785 8d9362f3b8aa
child 58002 01d31583f25c
equal deleted inserted replaced
57801:aff991f6e64d 57802:854e828d6b5b
    57     _stack_trim_lower_threshold(GCDrainStackTargetSize),
    57     _stack_trim_lower_threshold(GCDrainStackTargetSize),
    58     _trim_ticks(),
    58     _trim_ticks(),
    59     _old_gen_is_full(false),
    59     _old_gen_is_full(false),
    60     _num_optional_regions(optional_cset_length)
    60     _num_optional_regions(optional_cset_length)
    61 {
    61 {
    62   // we allocate G1YoungSurvRateNumRegions plus one entries, since
    62   // We allocate number of young gen regions in the collection set plus one
    63   // we "sacrifice" entry 0 to keep track of surviving bytes for
    63   // entries, since entry 0 keeps track of surviving bytes for non-young regions.
    64   // non-young regions (where the age is -1)
       
    65   // We also add a few elements at the beginning and at the end in
    64   // We also add a few elements at the beginning and at the end in
    66   // an attempt to eliminate cache contention
    65   // an attempt to eliminate cache contention
    67   size_t real_length = 1 + young_cset_length;
    66   size_t real_length = young_cset_length + 1;
    68   size_t array_length = PADDING_ELEM_NUM +
    67   size_t array_length = PADDING_ELEM_NUM + real_length + PADDING_ELEM_NUM;
    69                       real_length +
       
    70                       PADDING_ELEM_NUM;
       
    71   _surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC);
    68   _surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC);
    72   if (_surviving_young_words_base == NULL)
       
    73     vm_exit_out_of_memory(array_length * sizeof(size_t), OOM_MALLOC_ERROR,
       
    74                           "Not enough space for young surv histo.");
       
    75   _surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM;
    69   _surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM;
    76   memset(_surviving_young_words, 0, real_length * sizeof(size_t));
    70   memset(_surviving_young_words, 0, real_length * sizeof(size_t));
    77 
    71 
    78   _plab_allocator = new G1PLABAllocator(_g1h->allocator());
    72   _plab_allocator = new G1PLABAllocator(_g1h->allocator());
    79 
    73 
    92   _rdcq.flush();
    86   _rdcq.flush();
    93   // Update allocation statistics.
    87   // Update allocation statistics.
    94   _plab_allocator->flush_and_retire_stats();
    88   _plab_allocator->flush_and_retire_stats();
    95   _g1h->policy()->record_age_table(&_age_table);
    89   _g1h->policy()->record_age_table(&_age_table);
    96 
    90 
    97   uint length = _g1h->collection_set()->young_region_length();
    91   uint length = _g1h->collection_set()->young_region_length() + 1;
    98   for (uint region_index = 0; region_index < length; region_index++) {
    92   for (uint i = 0; i < length; i++) {
    99     surviving_young_words[region_index] += _surviving_young_words[region_index];
    93     surviving_young_words[i] += _surviving_young_words[i];
   100   }
    94   }
   101 }
    95 }
   102 
    96 
   103 G1ParScanThreadState::~G1ParScanThreadState() {
    97 G1ParScanThreadState::~G1ParScanThreadState() {
   104   delete _plab_allocator;
    98   delete _plab_allocator;
   224 
   218 
   225 oop G1ParScanThreadState::copy_to_survivor_space(G1HeapRegionAttr const region_attr,
   219 oop G1ParScanThreadState::copy_to_survivor_space(G1HeapRegionAttr const region_attr,
   226                                                  oop const old,
   220                                                  oop const old,
   227                                                  markWord const old_mark) {
   221                                                  markWord const old_mark) {
   228   const size_t word_sz = old->size();
   222   const size_t word_sz = old->size();
   229   HeapRegion* const from_region = _g1h->heap_region_containing(old);
       
   230   // +1 to make the -1 indexes valid...
       
   231   const int young_index = from_region->young_index_in_cset()+1;
       
   232   assert( (from_region->is_young() && young_index >  0) ||
       
   233          (!from_region->is_young() && young_index == 0), "invariant" );
       
   234 
   223 
   235   uint age = 0;
   224   uint age = 0;
   236   G1HeapRegionAttr dest_attr = next_region_attr(region_attr, old_mark, age);
   225   G1HeapRegionAttr dest_attr = next_region_attr(region_attr, old_mark, age);
   237   // The second clause is to prevent premature evacuation failure in case there
   226   // The second clause is to prevent premature evacuation failure in case there
   238   // is still space in survivor, but old gen is full.
   227   // is still space in survivor, but old gen is full.
   278 
   267 
   279   const oop obj = oop(obj_ptr);
   268   const oop obj = oop(obj_ptr);
   280   const oop forward_ptr = old->forward_to_atomic(obj, old_mark, memory_order_relaxed);
   269   const oop forward_ptr = old->forward_to_atomic(obj, old_mark, memory_order_relaxed);
   281   if (forward_ptr == NULL) {
   270   if (forward_ptr == NULL) {
   282     Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz);
   271     Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz);
       
   272 
       
   273     HeapRegion* const from_region = _g1h->heap_region_containing(old);
       
   274     const uint young_index = from_region->young_index_in_cset();
       
   275 
       
   276     assert((from_region->is_young() && young_index >  0) ||
       
   277            (!from_region->is_young() && young_index == 0), "invariant" );
   283 
   278 
   284     if (dest_attr.is_young()) {
   279     if (dest_attr.is_young()) {
   285       if (age < markWord::max_age) {
   280       if (age < markWord::max_age) {
   286         age++;
   281         age++;
   287       }
   282       }
   301     }
   296     }
   302 
   297 
   303     if (G1StringDedup::is_enabled()) {
   298     if (G1StringDedup::is_enabled()) {
   304       const bool is_from_young = region_attr.is_young();
   299       const bool is_from_young = region_attr.is_young();
   305       const bool is_to_young = dest_attr.is_young();
   300       const bool is_to_young = dest_attr.is_young();
   306       assert(is_from_young == _g1h->heap_region_containing(old)->is_young(),
   301       assert(is_from_young == from_region->is_young(),
   307              "sanity");
   302              "sanity");
   308       assert(is_to_young == _g1h->heap_region_containing(obj)->is_young(),
   303       assert(is_to_young == _g1h->heap_region_containing(obj)->is_young(),
   309              "sanity");
   304              "sanity");
   310       G1StringDedup::enqueue_from_evacuation(is_from_young,
   305       G1StringDedup::enqueue_from_evacuation(is_from_young,
   311                                              is_to_young,
   306                                              is_to_young,
   413                                                  size_t young_cset_length,
   408                                                  size_t young_cset_length,
   414                                                  size_t optional_cset_length) :
   409                                                  size_t optional_cset_length) :
   415     _g1h(g1h),
   410     _g1h(g1h),
   416     _rdcqs(rdcqs),
   411     _rdcqs(rdcqs),
   417     _states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC)),
   412     _states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC)),
   418     _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length, mtGC)),
   413     _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length + 1, mtGC)),
   419     _young_cset_length(young_cset_length),
   414     _young_cset_length(young_cset_length),
   420     _optional_cset_length(optional_cset_length),
   415     _optional_cset_length(optional_cset_length),
   421     _n_workers(n_workers),
   416     _n_workers(n_workers),
   422     _flushed(false) {
   417     _flushed(false) {
   423   for (uint i = 0; i < n_workers; ++i) {
   418   for (uint i = 0; i < n_workers; ++i) {
   424     _states[i] = NULL;
   419     _states[i] = NULL;
   425   }
   420   }
   426   memset(_surviving_young_words_total, 0, young_cset_length * sizeof(size_t));
   421   memset(_surviving_young_words_total, 0, (young_cset_length + 1) * sizeof(size_t));
   427 }
   422 }
   428 
   423 
   429 G1ParScanThreadStateSet::~G1ParScanThreadStateSet() {
   424 G1ParScanThreadStateSet::~G1ParScanThreadStateSet() {
   430   assert(_flushed, "thread local state from the per thread states should have been flushed");
   425   assert(_flushed, "thread local state from the per thread states should have been flushed");
   431   FREE_C_HEAP_ARRAY(G1ParScanThreadState*, _states);
   426   FREE_C_HEAP_ARRAY(G1ParScanThreadState*, _states);