hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp
author tonyp
Tue, 24 Aug 2010 17:24:33 -0400
changeset 7398 e4aa6d9bda09
parent 7397 5b173b4ca846
child 8103 65eafe3fb3c7
permissions -rw-r--r--
6974966: G1: unnecessary direct-to-old allocations Summary: This change revamps the slow allocation path of G1. Improvements include the following: a) Allocations directly to old regions are now totally banned. G1 now only allows allocations out of young regions (with the only exception being humongous regions). b) The thread that allocates a new region (which is now guaranteed to be young) does not dirty all its cards. Each thread that successfully allocates out of a young region is now responsible for dirtying the cards that corresponding to the "block" that just got allocated. c) allocate_new_tlab() and mem_allocate() are now implemented differently and TLAB allocations are only done by allocate_new_tlab(). d) If a thread schedules an evacuation pause in order to satisfy an allocation request, it will perform the allocation at the end of the safepoint so that the thread that initiated the GC also gets "first pick" of any space made available by the GC. e) If a thread is unable to allocate a humongous object it will schedule an evacuation pause in case it reclaims enough regions so that the humongous allocation can be satisfied aftewards. f) The G1 policy is more careful to set the young list target length to be the survivor number +1. g) Lots of code tidy up, removal, refactoring to make future changes easier. Reviewed-by: johnc, ysr
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     1
/*
6068
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
     2
 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     4
 *
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     7
 * published by the Free Software Foundation.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     8
 *
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    13
 * accompanied this code).
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    14
 *
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5033
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5033
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5033
diff changeset
    21
 * questions.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    22
 *
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    23
 */
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6247
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6247
diff changeset
    26
#include "gc_implementation/g1/concurrentG1Refine.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6247
diff changeset
    27
#include "gc_implementation/g1/concurrentG1RefineThread.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6247
diff changeset
    28
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6247
diff changeset
    29
#include "gc_implementation/g1/g1CollectorPolicy.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6247
diff changeset
    30
#include "gc_implementation/g1/g1RemSet.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6247
diff changeset
    31
#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6247
diff changeset
    32
#include "memory/space.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6247
diff changeset
    33
#include "runtime/atomic.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6247
diff changeset
    34
#include "utilities/copy.hpp"
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    35
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    36
// Possible sizes for the card counts cache: odd primes that roughly double in size.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    37
// (See jvmtiTagMap.cpp).
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    38
int ConcurrentG1Refine::_cc_cache_sizes[] = {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    39
        16381,    32771,    76831,    150001,   307261,
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    40
       614563,  1228891,  2457733,   4915219,  9830479,
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    41
     19660831, 39321619, 78643219, 157286461,       -1
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    42
  };
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    43
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    44
ConcurrentG1Refine::ConcurrentG1Refine() :
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    45
  _card_counts(NULL), _card_epochs(NULL),
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    46
  _n_card_counts(0), _max_n_card_counts(0),
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    47
  _cache_size_index(0), _expand_card_counts(false),
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    48
  _hot_cache(NULL),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    49
  _def_use_cache(false), _use_cache(false),
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    50
  _n_periods(0),
2881
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
    51
  _threads(NULL), _n_threads(0)
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    52
{
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    53
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    54
  // Ergomonically select initial concurrent refinement parameters
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    55
  if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    56
    FLAG_SET_DEFAULT(G1ConcRefinementGreenZone, MAX2<int>(ParallelGCThreads, 1));
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    57
  }
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    58
  set_green_zone(G1ConcRefinementGreenZone);
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    59
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    60
  if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    61
    FLAG_SET_DEFAULT(G1ConcRefinementYellowZone, green_zone() * 3);
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    62
  }
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    63
  set_yellow_zone(MAX2<int>(G1ConcRefinementYellowZone, green_zone()));
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    64
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    65
  if (FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    66
    FLAG_SET_DEFAULT(G1ConcRefinementRedZone, yellow_zone() * 2);
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    67
  }
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    68
  set_red_zone(MAX2<int>(G1ConcRefinementRedZone, yellow_zone()));
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    69
  _n_worker_threads = thread_num();
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    70
  // We need one extra thread to do the young gen rset size sampling.
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    71
  _n_threads = _n_worker_threads + 1;
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    72
  reset_threshold_step();
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    73
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    74
  _threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads);
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    75
  int worker_id_offset = (int)DirtyCardQueueSet::num_par_ids();
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    76
  ConcurrentG1RefineThread *next = NULL;
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    77
  for (int i = _n_threads - 1; i >= 0; i--) {
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    78
    ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, worker_id_offset, i);
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    79
    assert(t != NULL, "Conc refine should have been created");
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    80
    assert(t->cg1r() == this, "Conc refine thread should refer to this");
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    81
    _threads[i] = t;
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    82
    next = t;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    83
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    84
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    85
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    86
void ConcurrentG1Refine::reset_threshold_step() {
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    87
  if (FLAG_IS_DEFAULT(G1ConcRefinementThresholdStep)) {
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    88
    _thread_threshold_step = (yellow_zone() - green_zone()) / (worker_thread_num() + 1);
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    89
  } else {
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    90
    _thread_threshold_step = G1ConcRefinementThresholdStep;
2882
d508a8bac491 6841831: G1: assert(contains_reference(from),"We just added it!") fires
iveresov
parents: 2881
diff changeset
    91
  }
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    92
}
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    93
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    94
int ConcurrentG1Refine::thread_num() {
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    95
  return MAX2<int>((G1ConcRefinementThreads > 0) ? G1ConcRefinementThreads : ParallelGCThreads, 1);
2882
d508a8bac491 6841831: G1: assert(contains_reference(from),"We just added it!") fires
iveresov
parents: 2881
diff changeset
    96
}
d508a8bac491 6841831: G1: assert(contains_reference(from),"We just added it!") fires
iveresov
parents: 2881
diff changeset
    97
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    98
void ConcurrentG1Refine::init() {
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    99
  if (G1ConcRSLogCacheSize > 0) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   100
    _g1h = G1CollectedHeap::heap();
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   101
    _max_n_card_counts =
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   102
      (unsigned) (_g1h->g1_reserved_obj_bytes() >> CardTableModRefBS::card_shift);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   103
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   104
    size_t max_card_num = ((size_t)1 << (sizeof(unsigned)*BitsPerByte-1)) - 1;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   105
    guarantee(_max_n_card_counts < max_card_num, "card_num representation");
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   106
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   107
    int desired = _max_n_card_counts / InitialCacheFraction;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   108
    for (_cache_size_index = 0;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   109
              _cc_cache_sizes[_cache_size_index] >= 0; _cache_size_index++) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   110
      if (_cc_cache_sizes[_cache_size_index] >= desired) break;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   111
    }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   112
    _cache_size_index = MAX2(0, (_cache_size_index - 1));
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   113
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   114
    int initial_size = _cc_cache_sizes[_cache_size_index];
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   115
    if (initial_size < 0) initial_size = _max_n_card_counts;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   116
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   117
    // Make sure we don't go bigger than we will ever need
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   118
    _n_card_counts = MIN2((unsigned) initial_size, _max_n_card_counts);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   119
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   120
    _card_counts = NEW_C_HEAP_ARRAY(CardCountCacheEntry, _n_card_counts);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   121
    _card_epochs = NEW_C_HEAP_ARRAY(CardEpochCacheEntry, _n_card_counts);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   122
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   123
    Copy::fill_to_bytes(&_card_counts[0],
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   124
                        _n_card_counts * sizeof(CardCountCacheEntry));
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   125
    Copy::fill_to_bytes(&_card_epochs[0], _n_card_counts * sizeof(CardEpochCacheEntry));
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   126
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   127
    ModRefBarrierSet* bs = _g1h->mr_bs();
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   128
    guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   129
    _ct_bs = (CardTableModRefBS*)bs;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   130
    _ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start());
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   131
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   132
    _def_use_cache = true;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   133
    _use_cache = true;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   134
    _hot_cache_size = (1 << G1ConcRSLogCacheSize);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   135
    _hot_cache = NEW_C_HEAP_ARRAY(jbyte*, _hot_cache_size);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   136
    _n_hot = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   137
    _hot_cache_idx = 0;
3589
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   138
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   139
    // For refining the cards in the hot cache in parallel
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   140
    int n_workers = (ParallelGCThreads > 0 ?
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   141
                        _g1h->workers()->total_workers() : 1);
3589
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   142
    _hot_cache_par_chunk_size = MAX2(1, _hot_cache_size / n_workers);
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   143
    _hot_cache_par_claimed_idx = 0;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   144
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   145
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   146
2881
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   147
void ConcurrentG1Refine::stop() {
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   148
  if (_threads != NULL) {
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   149
    for (int i = 0; i < _n_threads; i++) {
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   150
      _threads[i]->stop();
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   151
    }
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   152
  }
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   153
}
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   154
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   155
void ConcurrentG1Refine::reinitialize_threads() {
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   156
  reset_threshold_step();
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   157
  if (_threads != NULL) {
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   158
    for (int i = 0; i < _n_threads; i++) {
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   159
      _threads[i]->initialize();
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   160
    }
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   161
  }
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   162
}
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   163
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   164
ConcurrentG1Refine::~ConcurrentG1Refine() {
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   165
  if (G1ConcRSLogCacheSize > 0) {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   166
    assert(_card_counts != NULL, "Logic");
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   167
    FREE_C_HEAP_ARRAY(CardCountCacheEntry, _card_counts);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   168
    assert(_card_epochs != NULL, "Logic");
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   169
    FREE_C_HEAP_ARRAY(CardEpochCacheEntry, _card_epochs);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   170
    assert(_hot_cache != NULL, "Logic");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   171
    FREE_C_HEAP_ARRAY(jbyte*, _hot_cache);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   172
  }
2881
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   173
  if (_threads != NULL) {
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   174
    for (int i = 0; i < _n_threads; i++) {
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   175
      delete _threads[i];
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   176
    }
2886
70bf7d429eba 6849122: G1: Typo introduced during implementation of the parallel refinement
iveresov
parents: 2882
diff changeset
   177
    FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   178
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   179
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   180
2881
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   181
void ConcurrentG1Refine::threads_do(ThreadClosure *tc) {
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   182
  if (_threads != NULL) {
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   183
    for (int i = 0; i < _n_threads; i++) {
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   184
      tc->do_thread(_threads[i]);
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   185
    }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   186
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   187
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   188
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   189
bool ConcurrentG1Refine::is_young_card(jbyte* card_ptr) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   190
  HeapWord* start = _ct_bs->addr_for(card_ptr);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   191
  HeapRegion* r = _g1h->heap_region_containing(start);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   192
  if (r != NULL && r->is_young()) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   193
    return true;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   194
  }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   195
  // This card is not associated with a heap region
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   196
  // so can't be young.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   197
  return false;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   198
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   199
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   200
jbyte* ConcurrentG1Refine::add_card_count(jbyte* card_ptr, int* count, bool* defer) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   201
  unsigned new_card_num = ptr_2_card_num(card_ptr);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   202
  unsigned bucket = hash(new_card_num);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   203
  assert(0 <= bucket && bucket < _n_card_counts, "Bounds");
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   204
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   205
  CardCountCacheEntry* count_ptr = &_card_counts[bucket];
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   206
  CardEpochCacheEntry* epoch_ptr = &_card_epochs[bucket];
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   207
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   208
  // We have to construct a new entry if we haven't updated the counts
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   209
  // during the current period, or if the count was updated for a
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   210
  // different card number.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   211
  unsigned int new_epoch = (unsigned int) _n_periods;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   212
  julong new_epoch_entry = make_epoch_entry(new_card_num, new_epoch);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   213
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   214
  while (true) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   215
    // Fetch the previous epoch value
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   216
    julong prev_epoch_entry = epoch_ptr->_value;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   217
    julong cas_res;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   218
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   219
    if (extract_epoch(prev_epoch_entry) != new_epoch) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   220
      // This entry has not yet been updated during this period.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   221
      // Note: we update the epoch value atomically to ensure
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   222
      // that there is only one winner that updates the cached
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   223
      // card_ptr value even though all the refine threads share
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   224
      // the same epoch value.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   225
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   226
      cas_res = (julong) Atomic::cmpxchg((jlong) new_epoch_entry,
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   227
                                         (volatile jlong*)&epoch_ptr->_value,
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   228
                                         (jlong) prev_epoch_entry);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   229
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   230
      if (cas_res == prev_epoch_entry) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   231
        // We have successfully won the race to update the
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   232
        // epoch and card_num value. Make it look like the
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   233
        // count and eviction count were previously cleared.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   234
        count_ptr->_count = 1;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   235
        count_ptr->_evict_count = 0;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   236
        *count = 0;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   237
        // We can defer the processing of card_ptr
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   238
        *defer = true;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   239
        return card_ptr;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   240
      }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   241
      // We did not win the race to update the epoch field, so some other
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   242
      // thread must have done it. The value that gets returned by CAS
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   243
      // should be the new epoch value.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   244
      assert(extract_epoch(cas_res) == new_epoch, "unexpected epoch");
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   245
      // We could 'continue' here or just re-read the previous epoch value
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   246
      prev_epoch_entry = epoch_ptr->_value;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   247
    }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   248
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   249
    // The epoch entry for card_ptr has been updated during this period.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   250
    unsigned old_card_num = extract_card_num(prev_epoch_entry);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   251
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   252
    // The card count that will be returned to caller
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   253
    *count = count_ptr->_count;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   254
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   255
    // Are we updating the count for the same card?
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   256
    if (new_card_num == old_card_num) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   257
      // Same card - just update the count. We could have more than one
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   258
      // thread racing to update count for the current card. It should be
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   259
      // OK not to use a CAS as the only penalty should be some missed
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   260
      // increments of the count which delays identifying the card as "hot".
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   261
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   262
      if (*count < max_jubyte) count_ptr->_count++;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   263
      // We can defer the processing of card_ptr
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   264
      *defer = true;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   265
      return card_ptr;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   266
    }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   267
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   268
    // Different card - evict old card info
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   269
    if (count_ptr->_evict_count < max_jubyte) count_ptr->_evict_count++;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   270
    if (count_ptr->_evict_count > G1CardCountCacheExpandThreshold) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   271
      // Trigger a resize the next time we clear
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   272
      _expand_card_counts = true;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   273
    }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   274
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   275
    cas_res = (julong) Atomic::cmpxchg((jlong) new_epoch_entry,
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   276
                                       (volatile jlong*)&epoch_ptr->_value,
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   277
                                       (jlong) prev_epoch_entry);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   278
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   279
    if (cas_res == prev_epoch_entry) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   280
      // We successfully updated the card num value in the epoch entry
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   281
      count_ptr->_count = 0; // initialize counter for new card num
6068
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   282
      jbyte* old_card_ptr = card_num_2_ptr(old_card_num);
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   283
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   284
      // Even though the region containg the card at old_card_num was not
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   285
      // in the young list when old_card_num was recorded in the epoch
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   286
      // cache it could have been added to the free list and subsequently
6068
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   287
      // added to the young list in the intervening time. See CR 6817995.
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   288
      // We do not deal with this case here - it will be handled in
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   289
      // HeapRegion::oops_on_card_seq_iterate_careful after it has been
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   290
      // determined that the region containing the card has been allocated
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   291
      // to, and it's safe to check the young type of the region.
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   292
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   293
      // We do not want to defer processing of card_ptr in this case
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   294
      // (we need to refine old_card_ptr and card_ptr)
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   295
      *defer = false;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   296
      return old_card_ptr;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   297
    }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   298
    // Someone else beat us - try again.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   299
  }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   300
}
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   301
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   302
jbyte* ConcurrentG1Refine::cache_insert(jbyte* card_ptr, bool* defer) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   303
  int count;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   304
  jbyte* cached_ptr = add_card_count(card_ptr, &count, defer);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   305
  assert(cached_ptr != NULL, "bad cached card ptr");
4887
c6e9df29a2cf 6914402: G1: assert(!is_young_card(cached_ptr),"shouldn't get a card in young region")
johnc
parents: 4481
diff changeset
   306
6068
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   307
  // We've just inserted a card pointer into the card count cache
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   308
  // and got back the card that we just inserted or (evicted) the
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   309
  // previous contents of that count slot.
4887
c6e9df29a2cf 6914402: G1: assert(!is_young_card(cached_ptr),"shouldn't get a card in young region")
johnc
parents: 4481
diff changeset
   310
6068
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   311
  // The card we got back could be in a young region. When the
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   312
  // returned card (if evicted) was originally inserted, we had
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   313
  // determined that its containing region was not young. However
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   314
  // it is possible for the region to be freed during a cleanup
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   315
  // pause, then reallocated and tagged as young which will result
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   316
  // in the returned card residing in a young region.
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   317
  //
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   318
  // We do not deal with this case here - the change from non-young
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   319
  // to young could be observed at any time - it will be handled in
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   320
  // HeapRegion::oops_on_card_seq_iterate_careful after it has been
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   321
  // determined that the region containing the card has been allocated
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   322
  // to.
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   323
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   324
  // The card pointer we obtained from card count cache is not hot
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   325
  // so do not store it in the cache; return it for immediate
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   326
  // refining.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   327
  if (count < G1ConcRSHotCardLimit) {
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   328
    return cached_ptr;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   329
  }
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   330
6068
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   331
  // Otherwise, the pointer we got from the _card_counts cache is hot.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   332
  jbyte* res = NULL;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   333
  MutexLockerEx x(HotCardCache_lock, Mutex::_no_safepoint_check_flag);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   334
  if (_n_hot == _hot_cache_size) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   335
    res = _hot_cache[_hot_cache_idx];
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   336
    _n_hot--;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   337
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   338
  // Now _n_hot < _hot_cache_size, and we can insert at _hot_cache_idx.
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   339
  _hot_cache[_hot_cache_idx] = cached_ptr;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   340
  _hot_cache_idx++;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   341
  if (_hot_cache_idx == _hot_cache_size) _hot_cache_idx = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   342
  _n_hot++;
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   343
6068
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   344
  // The card obtained from the hot card cache could be in a young
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   345
  // region. See above on how this can happen.
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   346
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   347
  return res;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   348
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   349
6247
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   350
void ConcurrentG1Refine::clean_up_cache(int worker_i,
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   351
                                        G1RemSet* g1rs,
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   352
                                        DirtyCardQueue* into_cset_dcq) {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   353
  assert(!use_cache(), "cache should be disabled");
3589
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   354
  int start_idx;
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   355
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   356
  while ((start_idx = _hot_cache_par_claimed_idx) < _n_hot) { // read once
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   357
    int end_idx = start_idx + _hot_cache_par_chunk_size;
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   358
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   359
    if (start_idx ==
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   360
        Atomic::cmpxchg(end_idx, &_hot_cache_par_claimed_idx, start_idx)) {
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   361
      // The current worker has successfully claimed the chunk [start_idx..end_idx)
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   362
      end_idx = MIN2(end_idx, _n_hot);
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   363
      for (int i = start_idx; i < end_idx; i++) {
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   364
        jbyte* entry = _hot_cache[i];
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   365
        if (entry != NULL) {
6247
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   366
          if (g1rs->concurrentRefineOneCard(entry, worker_i, true)) {
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   367
            // 'entry' contains references that point into the current
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   368
            // collection set. We need to record 'entry' in the DCQS
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   369
            // that's used for that purpose.
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   370
            //
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   371
            // The only time we care about recording cards that contain
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   372
            // references that point into the collection set is during
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   373
            // RSet updating while within an evacuation pause.
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   374
            // In this case worker_i should be the id of a GC worker thread
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   375
            assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   376
            assert(worker_i < (int) DirtyCardQueueSet::num_par_ids(), "incorrect worker id");
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   377
            into_cset_dcq->enqueue(entry);
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   378
          }
3589
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   379
        }
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   380
      }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   381
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   382
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   383
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   384
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   385
void ConcurrentG1Refine::expand_card_count_cache() {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   386
  if (_n_card_counts < _max_n_card_counts) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   387
    int new_idx = _cache_size_index+1;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   388
    int new_size = _cc_cache_sizes[new_idx];
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   389
    if (new_size < 0) new_size = _max_n_card_counts;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   390
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   391
    // Make sure we don't go bigger than we will ever need
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   392
    new_size = MIN2((unsigned) new_size, _max_n_card_counts);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   393
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   394
    // Expand the card count and card epoch tables
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   395
    if (new_size > (int)_n_card_counts) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   396
      // We can just free and allocate a new array as we're
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   397
      // not interested in preserving the contents
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   398
      assert(_card_counts != NULL, "Logic!");
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   399
      assert(_card_epochs != NULL, "Logic!");
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   400
      FREE_C_HEAP_ARRAY(CardCountCacheEntry, _card_counts);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   401
      FREE_C_HEAP_ARRAY(CardEpochCacheEntry, _card_epochs);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   402
      _n_card_counts = new_size;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   403
      _card_counts = NEW_C_HEAP_ARRAY(CardCountCacheEntry, _n_card_counts);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   404
      _card_epochs = NEW_C_HEAP_ARRAY(CardEpochCacheEntry, _n_card_counts);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   405
      _cache_size_index = new_idx;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   406
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   407
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   408
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   409
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   410
void ConcurrentG1Refine::clear_and_record_card_counts() {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   411
  if (G1ConcRSLogCacheSize == 0) return;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   412
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   413
#ifndef PRODUCT
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   414
  double start = os::elapsedTime();
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   415
#endif
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   416
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   417
  if (_expand_card_counts) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   418
    expand_card_count_cache();
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   419
    _expand_card_counts = false;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   420
    // Only need to clear the epochs.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   421
    Copy::fill_to_bytes(&_card_epochs[0], _n_card_counts * sizeof(CardEpochCacheEntry));
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   422
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   423
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   424
  int this_epoch = (int) _n_periods;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   425
  assert((this_epoch+1) <= max_jint, "to many periods");
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   426
  // Update epoch
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   427
  _n_periods++;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   428
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   429
#ifndef PRODUCT
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   430
  double elapsed = os::elapsedTime() - start;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   431
  _g1h->g1_policy()->record_cc_clear_time(elapsed * 1000.0);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   432
#endif
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   433
}
4022
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   434
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   435
void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const {
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   436
  for (int i = 0; i < _n_threads; ++i) {
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   437
    _threads[i]->print_on(st);
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   438
    st->cr();
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   439
  }
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   440
}