hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp
author tonyp
Wed, 25 Jan 2012 12:58:23 -0500
changeset 11584 e1df4d08a1f4
parent 8929 33175c0c6b9b
child 13288 331d5b6725f3
child 13195 be27e1b6a4b9
permissions -rw-r--r--
7127706: G1: re-enable survivors during the initial-mark pause Summary: Re-enable survivors during the initial-mark pause. Afterwards, the concurrent marking threads have to scan them and mark everything reachable from them. The next GC will have to wait for the survivors to be scanned. Reviewed-by: brutisso, johnc
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
/*
8103
65eafe3fb3c7 6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents: 7397
diff changeset
     2
 * Copyright (c) 2001, 2011, 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"
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
    34
#include "runtime/java.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6247
diff changeset
    35
#include "utilities/copy.hpp"
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    36
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    37
// 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
    38
// (See jvmtiTagMap.cpp).
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
    39
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
    40
#define MAX_SIZE ((size_t) -1)
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
    41
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
    42
size_t ConcurrentG1Refine::_cc_cache_sizes[] = {
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
    43
          16381,    32771,    76831,    150001,   307261,
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
    44
         614563,  1228891,  2457733,   4915219,  9830479,
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
    45
       19660831, 39321619, 78643219, 157286461,  MAX_SIZE
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    46
  };
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    47
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    48
ConcurrentG1Refine::ConcurrentG1Refine() :
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    49
  _card_counts(NULL), _card_epochs(NULL),
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
    50
  _n_card_counts(0), _max_cards(0), _max_n_card_counts(0),
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
    51
  _cache_size_index(0), _expand_card_counts(false),
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    52
  _hot_cache(NULL),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    53
  _def_use_cache(false), _use_cache(false),
8929
33175c0c6b9b 7033292: G1: nightly failure: Non-dirty cards in region that should be dirty
tonyp
parents: 8926
diff changeset
    54
  // We initialize the epochs of the array to 0. By initializing
33175c0c6b9b 7033292: G1: nightly failure: Non-dirty cards in region that should be dirty
tonyp
parents: 8926
diff changeset
    55
  // _n_periods to 1 and not 0 we automatically invalidate all the
33175c0c6b9b 7033292: G1: nightly failure: Non-dirty cards in region that should be dirty
tonyp
parents: 8926
diff changeset
    56
  // entries on the array. Otherwise we might accidentally think that
33175c0c6b9b 7033292: G1: nightly failure: Non-dirty cards in region that should be dirty
tonyp
parents: 8926
diff changeset
    57
  // we claimed a card that was in fact never set (see CR7033292).
33175c0c6b9b 7033292: G1: nightly failure: Non-dirty cards in region that should be dirty
tonyp
parents: 8926
diff changeset
    58
  _n_periods(1),
2881
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
    59
  _threads(NULL), _n_threads(0)
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    60
{
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    61
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    62
  // Ergomonically select initial concurrent refinement parameters
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    63
  if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    64
    FLAG_SET_DEFAULT(G1ConcRefinementGreenZone, MAX2<int>(ParallelGCThreads, 1));
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    65
  }
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    66
  set_green_zone(G1ConcRefinementGreenZone);
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
  if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    69
    FLAG_SET_DEFAULT(G1ConcRefinementYellowZone, green_zone() * 3);
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    70
  }
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    71
  set_yellow_zone(MAX2<int>(G1ConcRefinementYellowZone, green_zone()));
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    72
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    73
  if (FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    74
    FLAG_SET_DEFAULT(G1ConcRefinementRedZone, yellow_zone() * 2);
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    75
  }
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    76
  set_red_zone(MAX2<int>(G1ConcRefinementRedZone, yellow_zone()));
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    77
  _n_worker_threads = thread_num();
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    78
  // We need one extra thread to do the young gen rset size sampling.
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    79
  _n_threads = _n_worker_threads + 1;
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    80
  reset_threshold_step();
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    81
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    82
  _threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads);
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    83
  int worker_id_offset = (int)DirtyCardQueueSet::num_par_ids();
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    84
  ConcurrentG1RefineThread *next = NULL;
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    85
  for (int i = _n_threads - 1; i >= 0; i--) {
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    86
    ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, worker_id_offset, i);
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    87
    assert(t != NULL, "Conc refine should have been created");
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    88
    assert(t->cg1r() == this, "Conc refine thread should refer to this");
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    89
    _threads[i] = t;
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    90
    next = t;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    91
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    92
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    93
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    94
void ConcurrentG1Refine::reset_threshold_step() {
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    95
  if (FLAG_IS_DEFAULT(G1ConcRefinementThresholdStep)) {
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    96
    _thread_threshold_step = (yellow_zone() - green_zone()) / (worker_thread_num() + 1);
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
    97
  } else {
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
    98
    _thread_threshold_step = G1ConcRefinementThresholdStep;
2882
d508a8bac491 6841831: G1: assert(contains_reference(from),"We just added it!") fires
iveresov
parents: 2881
diff changeset
    99
  }
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   100
}
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   101
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   102
int ConcurrentG1Refine::thread_num() {
5033
55f476a32544 6928059: G1: command line parameter renaming
tonyp
parents: 4887
diff changeset
   103
  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
   104
}
d508a8bac491 6841831: G1: assert(contains_reference(from),"We just added it!") fires
iveresov
parents: 2881
diff changeset
   105
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   106
void ConcurrentG1Refine::init() {
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   107
  if (G1ConcRSLogCacheSize > 0) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   108
    _g1h = G1CollectedHeap::heap();
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   109
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   110
    _max_cards = _g1h->max_capacity() >> CardTableModRefBS::card_shift;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   111
    _max_n_card_counts = _max_cards * G1MaxHotCardCountSizePercent / 100;
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   112
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   113
    size_t max_card_num = ((size_t)1 << (sizeof(unsigned)*BitsPerByte-1)) - 1;
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   114
    guarantee(_max_cards < max_card_num, "card_num representation");
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   115
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   116
    // We need _n_card_counts to be less than _max_n_card_counts here
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   117
    // so that the expansion call (below) actually allocates the
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   118
    // _counts and _epochs arrays.
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   119
    assert(_n_card_counts == 0, "pre-condition");
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   120
    assert(_max_n_card_counts > 0, "pre-condition");
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   121
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   122
    // Find the index into cache size array that is of a size that's
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   123
    // large enough to hold desired_sz.
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   124
    size_t desired_sz = _max_cards / InitialCacheFraction;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   125
    int desired_sz_index = 0;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   126
    while (_cc_cache_sizes[desired_sz_index] < desired_sz) {
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   127
      desired_sz_index += 1;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   128
      assert(desired_sz_index <  MAX_CC_CACHE_INDEX, "invariant");
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   129
    }
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   130
    assert(desired_sz_index <  MAX_CC_CACHE_INDEX, "invariant");
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   131
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   132
    // If the desired_sz value is between two sizes then
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   133
    // _cc_cache_sizes[desired_sz_index-1] < desired_sz <= _cc_cache_sizes[desired_sz_index]
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   134
    // we will start with the lower size in the optimistic expectation that
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   135
    // we will not need to expand up. Note desired_sz_index could also be 0.
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   136
    if (desired_sz_index > 0 &&
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   137
        _cc_cache_sizes[desired_sz_index] > desired_sz) {
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   138
      desired_sz_index -= 1;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   139
    }
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   140
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   141
    if (!expand_card_count_cache(desired_sz_index)) {
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   142
      // Allocation was unsuccessful - exit
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   143
      vm_exit_during_initialization("Could not reserve enough space for card count cache");
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   144
    }
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   145
    assert(_n_card_counts > 0, "post-condition");
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   146
    assert(_cache_size_index == desired_sz_index, "post-condition");
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   147
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   148
    Copy::fill_to_bytes(&_card_counts[0],
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   149
                        _n_card_counts * sizeof(CardCountCacheEntry));
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   150
    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
   151
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   152
    ModRefBarrierSet* bs = _g1h->mr_bs();
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   153
    guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   154
    _ct_bs = (CardTableModRefBS*)bs;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   155
    _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
   156
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   157
    _def_use_cache = true;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   158
    _use_cache = true;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   159
    _hot_cache_size = (1 << G1ConcRSLogCacheSize);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   160
    _hot_cache = NEW_C_HEAP_ARRAY(jbyte*, _hot_cache_size);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   161
    _n_hot = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   162
    _hot_cache_idx = 0;
3589
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   163
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   164
    // For refining the cards in the hot cache in parallel
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   165
    int n_workers = (ParallelGCThreads > 0 ?
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   166
                        _g1h->workers()->total_workers() : 1);
3589
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   167
    _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
   168
    _hot_cache_par_claimed_idx = 0;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   169
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   170
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   171
2881
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   172
void ConcurrentG1Refine::stop() {
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
      _threads[i]->stop();
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   176
    }
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   177
  }
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   178
}
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   179
4481
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   180
void ConcurrentG1Refine::reinitialize_threads() {
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   181
  reset_threshold_step();
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   182
  if (_threads != NULL) {
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   183
    for (int i = 0; i < _n_threads; i++) {
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   184
      _threads[i]->initialize();
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   185
    }
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   186
  }
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   187
}
de92ec484f5e 6862387: tune concurrent refinement further
iveresov
parents: 4022
diff changeset
   188
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   189
ConcurrentG1Refine::~ConcurrentG1Refine() {
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   190
  if (G1ConcRSLogCacheSize > 0) {
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   191
    // Please see the comment in allocate_card_count_cache
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   192
    // for why we call os::malloc() and os::free() directly.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   193
    assert(_card_counts != NULL, "Logic");
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   194
    os::free(_card_counts);
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   195
    assert(_card_epochs != NULL, "Logic");
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   196
    os::free(_card_epochs);
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   197
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   198
    assert(_hot_cache != NULL, "Logic");
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   199
    FREE_C_HEAP_ARRAY(jbyte*, _hot_cache);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   200
  }
2881
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   201
  if (_threads != NULL) {
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   202
    for (int i = 0; i < _n_threads; i++) {
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   203
      delete _threads[i];
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   204
    }
2886
70bf7d429eba 6849122: G1: Typo introduced during implementation of the parallel refinement
iveresov
parents: 2882
diff changeset
   205
    FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   206
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   207
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   208
2881
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   209
void ConcurrentG1Refine::threads_do(ThreadClosure *tc) {
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   210
  if (_threads != NULL) {
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   211
    for (int i = 0; i < _n_threads; i++) {
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   212
      tc->do_thread(_threads[i]);
74a1337e4acc 6484957: G1: parallel concurrent refinement
iveresov
parents: 2249
diff changeset
   213
    }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   214
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   215
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   216
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   217
bool ConcurrentG1Refine::is_young_card(jbyte* card_ptr) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   218
  HeapWord* start = _ct_bs->addr_for(card_ptr);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   219
  HeapRegion* r = _g1h->heap_region_containing(start);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   220
  if (r != NULL && r->is_young()) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   221
    return true;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   222
  }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   223
  // 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
   224
  // so can't be young.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   225
  return false;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   226
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   227
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   228
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
   229
  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
   230
  unsigned bucket = hash(new_card_num);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   231
  assert(0 <= bucket && bucket < _n_card_counts, "Bounds");
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   232
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   233
  CardCountCacheEntry* count_ptr = &_card_counts[bucket];
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   234
  CardEpochCacheEntry* epoch_ptr = &_card_epochs[bucket];
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   235
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   236
  // 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
   237
  // 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
   238
  // different card number.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   239
  unsigned int new_epoch = (unsigned int) _n_periods;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   240
  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
   241
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   242
  while (true) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   243
    // Fetch the previous epoch value
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   244
    julong prev_epoch_entry = epoch_ptr->_value;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   245
    julong cas_res;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   246
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   247
    if (extract_epoch(prev_epoch_entry) != new_epoch) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   248
      // 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
   249
      // 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
   250
      // 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
   251
      // 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
   252
      // the same epoch value.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   253
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   254
      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
   255
                                         (volatile jlong*)&epoch_ptr->_value,
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   256
                                         (jlong) prev_epoch_entry);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   257
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   258
      if (cas_res == prev_epoch_entry) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   259
        // 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
   260
        // 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
   261
        // count and eviction count were previously cleared.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   262
        count_ptr->_count = 1;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   263
        count_ptr->_evict_count = 0;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   264
        *count = 0;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   265
        // We can defer the processing of card_ptr
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   266
        *defer = true;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   267
        return card_ptr;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   268
      }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   269
      // 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
   270
      // 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
   271
      // should be the new epoch value.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   272
      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
   273
      // 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
   274
      prev_epoch_entry = epoch_ptr->_value;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   275
    }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   276
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   277
    // 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
   278
    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
   279
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   280
    // 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
   281
    *count = count_ptr->_count;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   282
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   283
    // 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
   284
    if (new_card_num == old_card_num) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   285
      // 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
   286
      // 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
   287
      // 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
   288
      // 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
   289
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   290
      if (*count < max_jubyte) count_ptr->_count++;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   291
      // We can defer the processing of card_ptr
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   292
      *defer = true;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   293
      return card_ptr;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   294
    }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   295
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   296
    // Different card - evict old card info
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   297
    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
   298
    if (count_ptr->_evict_count > G1CardCountCacheExpandThreshold) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   299
      // Trigger a resize the next time we clear
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   300
      _expand_card_counts = true;
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
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   303
    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
   304
                                       (volatile jlong*)&epoch_ptr->_value,
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   305
                                       (jlong) prev_epoch_entry);
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   306
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   307
    if (cas_res == prev_epoch_entry) {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   308
      // 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
   309
      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
   310
      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
   311
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   312
      // 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
   313
      // 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
   314
      // 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
   315
      // 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
   316
      // 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
   317
      // 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
   318
      // 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
   319
      // 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
   320
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   321
      // 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
   322
      // (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
   323
      *defer = false;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   324
      return old_card_ptr;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   325
    }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   326
    // Someone else beat us - try again.
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   327
  }
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   328
}
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   329
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   330
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
   331
  int count;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   332
  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
   333
  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
   334
6068
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   335
  // 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
   336
  // 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
   337
  // 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
   338
6068
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   339
  // 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
   340
  // 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
   341
  // 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
   342
  // 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
   343
  // 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
   344
  // 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
   345
  //
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   346
  // 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
   347
  // 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
   348
  // 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
   349
  // 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
   350
  // to.
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   351
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   352
  // 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
   353
  // 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
   354
  // refining.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   355
  if (count < G1ConcRSHotCardLimit) {
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   356
    return cached_ptr;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   357
  }
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   358
6068
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   359
  // 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
   360
  jbyte* res = NULL;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   361
  MutexLockerEx x(HotCardCache_lock, Mutex::_no_safepoint_check_flag);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   362
  if (_n_hot == _hot_cache_size) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   363
    res = _hot_cache[_hot_cache_idx];
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   364
    _n_hot--;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   365
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   366
  // 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
   367
  _hot_cache[_hot_cache_idx] = cached_ptr;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   368
  _hot_cache_idx++;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   369
  if (_hot_cache_idx == _hot_cache_size) _hot_cache_idx = 0;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   370
  _n_hot++;
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   371
6068
80ef41e75a2d 6956639: G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
johnc
parents: 5547
diff changeset
   372
  // 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
   373
  // 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
   374
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   375
  return res;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   376
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   377
6247
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   378
void ConcurrentG1Refine::clean_up_cache(int worker_i,
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   379
                                        G1RemSet* g1rs,
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   380
                                        DirtyCardQueue* into_cset_dcq) {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   381
  assert(!use_cache(), "cache should be disabled");
3589
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   382
  int start_idx;
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   383
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   384
  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
   385
    int end_idx = start_idx + _hot_cache_par_chunk_size;
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   386
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   387
    if (start_idx ==
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   388
        Atomic::cmpxchg(end_idx, &_hot_cache_par_claimed_idx, start_idx)) {
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   389
      // 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
   390
      end_idx = MIN2(end_idx, _n_hot);
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   391
      for (int i = start_idx; i < end_idx; i++) {
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   392
        jbyte* entry = _hot_cache[i];
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   393
        if (entry != NULL) {
6247
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   394
          if (g1rs->concurrentRefineOneCard(entry, worker_i, true)) {
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   395
            // 'entry' contains references that point into the current
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   396
            // collection set. We need to record 'entry' in the DCQS
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   397
            // that's used for that purpose.
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   398
            //
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   399
            // The only time we care about recording cards that contain
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   400
            // references that point into the collection set is during
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   401
            // RSet updating while within an evacuation pause.
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   402
            // 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
   403
            assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
8683
9d31cebc0f6e 7023747: G1: too strict assert in RefineRecordRefsIntoCSCardTableEntryClosure::do_card_ptr in g1RemSet.cpp
brutisso
parents: 8103
diff changeset
   404
            assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "incorrect worker id");
6247
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   405
            into_cset_dcq->enqueue(entry);
00e5cc407d03 6814437: G1: remove the _new_refs array
johnc
parents: 6068
diff changeset
   406
          }
3589
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   407
        }
abdd970c243d 6865703: G1: Parallelize hot card cache cleanup
johnc
parents: 3261
diff changeset
   408
      }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   409
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   410
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   411
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   412
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   413
// The arrays used to hold the card counts and the epochs must have
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   414
// a 1:1 correspondence. Hence they are allocated and freed together
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   415
// Returns true if the allocations of both the counts and epochs
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   416
// were successful; false otherwise.
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   417
bool ConcurrentG1Refine::allocate_card_count_cache(size_t n,
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   418
                                                   CardCountCacheEntry** counts,
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   419
                                                   CardEpochCacheEntry** epochs) {
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   420
  // We call the allocation/free routines directly for the counts
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   421
  // and epochs arrays. The NEW_C_HEAP_ARRAY/FREE_C_HEAP_ARRAY
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   422
  // macros call AllocateHeap and FreeHeap respectively.
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   423
  // AllocateHeap will call vm_exit_out_of_memory in the event
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   424
  // of an allocation failure and abort the JVM. With the
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   425
  // _counts/epochs arrays we only need to abort the JVM if the
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   426
  // initial allocation of these arrays fails.
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   427
  //
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   428
  // Additionally AllocateHeap/FreeHeap do some tracing of
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   429
  // allocate/free calls so calling one without calling the
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   430
  // other can cause inconsistencies in the tracing. So we
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   431
  // call neither.
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   432
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   433
  assert(*counts == NULL, "out param");
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   434
  assert(*epochs == NULL, "out param");
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   435
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   436
  size_t counts_size = n * sizeof(CardCountCacheEntry);
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   437
  size_t epochs_size = n * sizeof(CardEpochCacheEntry);
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   438
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   439
  *counts = (CardCountCacheEntry*) os::malloc(counts_size);
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   440
  if (*counts == NULL) {
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   441
    // allocation was unsuccessful
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   442
    return false;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   443
  }
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   444
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   445
  *epochs = (CardEpochCacheEntry*) os::malloc(epochs_size);
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   446
  if (*epochs == NULL) {
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   447
    // allocation was unsuccessful - free counts array
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   448
    assert(*counts != NULL, "must be");
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   449
    os::free(*counts);
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   450
    *counts = NULL;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   451
    return false;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   452
  }
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   453
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   454
  // We successfully allocated both counts and epochs
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   455
  return true;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   456
}
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   457
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   458
// Returns true if the card counts/epochs cache was
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   459
// successfully expanded; false otherwise.
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   460
bool ConcurrentG1Refine::expand_card_count_cache(int cache_size_idx) {
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   461
  // Can we expand the card count and epoch tables?
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   462
  if (_n_card_counts < _max_n_card_counts) {
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   463
    assert(cache_size_idx >= 0 && cache_size_idx  < MAX_CC_CACHE_INDEX, "oob");
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   464
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   465
    size_t cache_size = _cc_cache_sizes[cache_size_idx];
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   466
    // Make sure we don't go bigger than we will ever need
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   467
    cache_size = MIN2(cache_size, _max_n_card_counts);
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   468
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   469
    // Should we expand the card count and card epoch tables?
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   470
    if (cache_size > _n_card_counts) {
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   471
      // We have been asked to allocate new, larger, arrays for
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   472
      // the card counts and the epochs. Attempt the allocation
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   473
      // of both before we free the existing arrays in case
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   474
      // the allocation is unsuccessful...
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   475
      CardCountCacheEntry* counts = NULL;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   476
      CardEpochCacheEntry* epochs = NULL;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   477
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   478
      if (allocate_card_count_cache(cache_size, &counts, &epochs)) {
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   479
        // Allocation was successful.
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   480
        // We can just free the old arrays; we're
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   481
        // not interested in preserving the contents
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   482
        if (_card_counts != NULL) os::free(_card_counts);
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   483
        if (_card_epochs != NULL) os::free(_card_epochs);
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   484
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   485
        // Cache the size of the arrays and the index that got us there.
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   486
        _n_card_counts = cache_size;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   487
        _cache_size_index = cache_size_idx;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   488
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   489
        _card_counts = counts;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   490
        _card_epochs = epochs;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   491
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   492
        // We successfully allocated/expanded the caches.
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   493
        return true;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   494
      }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   495
    }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   496
  }
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   497
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   498
  // We did not successfully expand the caches.
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   499
  return false;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   500
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   501
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   502
void ConcurrentG1Refine::clear_and_record_card_counts() {
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   503
  if (G1ConcRSLogCacheSize == 0) return;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   504
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   505
#ifndef PRODUCT
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   506
  double start = os::elapsedTime();
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   507
#endif
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   508
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   509
  if (_expand_card_counts) {
8926
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   510
    int new_idx = _cache_size_index + 1;
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   511
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   512
    if (expand_card_count_cache(new_idx)) {
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   513
      // Allocation was successful and  _n_card_counts has
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   514
      // been updated to the new size. We only need to clear
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   515
      // the epochs so we don't read a bogus epoch value
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   516
      // when inserting a card into the hot card cache.
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   517
      Copy::fill_to_bytes(&_card_epochs[0], _n_card_counts * sizeof(CardEpochCacheEntry));
717a49db1743 7026932: G1: No need to abort VM when card count cache expansion fails
johnc
parents: 8683
diff changeset
   518
    }
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   519
    _expand_card_counts = false;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   520
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   521
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   522
  int this_epoch = (int) _n_periods;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   523
  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
   524
  // Update epoch
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   525
  _n_periods++;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   526
3590
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   527
#ifndef PRODUCT
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   528
  double elapsed = os::elapsedTime() - start;
a268fa66d7fb 6819077: G1: first GC thread coming late into the GC.
johnc
parents: 3589
diff changeset
   529
  _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
   530
#endif
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   531
}
4022
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   532
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   533
void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const {
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   534
  for (int i = 0; i < _n_threads; ++i) {
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   535
    _threads[i]->print_on(st);
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   536
    st->cr();
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   537
  }
2ec87d5043f7 6885041: G1: inconsistent thread dump
tonyp
parents: 3590
diff changeset
   538
}