hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
author johnc
Thu, 09 May 2013 11:16:39 -0700
changeset 17327 4bd0581aa231
parent 12934 f9bc0e664918
child 18025 b7bcf7497f93
permissions -rw-r--r--
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap Summary: Refactor G1's hot card cache and card counts table into their own files. Simplify the card counts table, including removing the encoding of the card index in each entry. The card counts table now has a 1:1 correspondence with the cards spanned by heap. Space for the card counts table is reserved from virtual memory (rather than C heap) during JVM startup and is committed/expanded when the heap is expanded. Changes were also reviewed-by Vitaly Davidovich. Reviewed-by: tschatzl, jmasa
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
/*
11576
e0bef5ca4602 6976060: G1: humongous object allocations should initiate marking cycles when necessary
brutisso
parents: 10769
diff changeset
     2
 * Copyright (c) 2001, 2012, 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: 4458
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4458
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: 4458
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: 6058
diff changeset
    25
#include "precompiled.hpp"
10769
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
    26
#include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6058
diff changeset
    27
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6058
diff changeset
    28
#include "gc_implementation/g1/g1CollectorPolicy.hpp"
12378
ed44b9ecfa2f 7160728: Introduce an extra logging level for G1 logging
brutisso
parents: 12227
diff changeset
    29
#include "gc_implementation/g1/g1Log.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6058
diff changeset
    30
#include "gc_implementation/g1/vm_operations_g1.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6058
diff changeset
    31
#include "gc_implementation/shared/isGCActiveMark.hpp"
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    32
#include "gc_implementation/g1/vm_operations_g1.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6058
diff changeset
    33
#include "runtime/interfaceSupport.hpp"
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    34
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    35
VM_G1CollectForAllocation::VM_G1CollectForAllocation(
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    36
                                                  unsigned int gc_count_before,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    37
                                                  size_t word_size)
12227
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    38
  : VM_G1OperationWithAllocRequest(gc_count_before, word_size,
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    39
                                   GCCause::_allocation_failure) {
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    40
  guarantee(word_size > 0, "an allocation should always be requested");
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    41
}
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    42
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    43
void VM_G1CollectForAllocation::doit() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    44
  G1CollectedHeap* g1h = G1CollectedHeap::heap();
12628
bd8e0e8f8e5c 7168294: G1: Some Full GCs incorrectly report GC cause as "No GC"
johnc
parents: 12378
diff changeset
    45
  GCCauseSetter x(g1h, _gc_cause);
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    46
  _result = g1h->satisfy_failed_allocation(_word_size, &_pause_succeeded);
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    47
  assert(_result == NULL || _pause_succeeded,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    48
         "if we get back a result, the pause should have succeeded");
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    49
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    50
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    51
void VM_G1CollectFull::doit() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    52
  G1CollectedHeap* g1h = G1CollectedHeap::heap();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    53
  GCCauseSetter x(g1h, _gc_cause);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    54
  g1h->do_full_collection(false /* clear_all_soft_refs */);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    55
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    56
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    57
VM_G1IncCollectionPause::VM_G1IncCollectionPause(
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    58
                                      unsigned int   gc_count_before,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    59
                                      size_t         word_size,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    60
                                      bool           should_initiate_conc_mark,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    61
                                      double         target_pause_time_ms,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    62
                                      GCCause::Cause gc_cause)
12227
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    63
  : VM_G1OperationWithAllocRequest(gc_count_before, word_size, gc_cause),
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    64
    _should_initiate_conc_mark(should_initiate_conc_mark),
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    65
    _target_pause_time_ms(target_pause_time_ms),
12227
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    66
    _should_retry_gc(false),
12934
f9bc0e664918 7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents: 12628
diff changeset
    67
    _old_marking_cycles_completed_before(0) {
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    68
  guarantee(target_pause_time_ms > 0.0,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    69
            err_msg("target_pause_time_ms = %1.6lf should be positive",
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    70
                    target_pause_time_ms));
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    71
  guarantee(word_size == 0 || gc_cause == GCCause::_g1_inc_collection_pause,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    72
            "we can only request an allocation if the GC cause is for "
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    73
            "an incremental GC pause");
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    74
  _gc_cause = gc_cause;
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    75
}
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    76
12227
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    77
bool VM_G1IncCollectionPause::doit_prologue() {
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    78
  bool res = VM_GC_Operation::doit_prologue();
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    79
  if (!res) {
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    80
    if (_should_initiate_conc_mark) {
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    81
      // The prologue can fail for a couple of reasons. The first is that another GC
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    82
      // got scheduled and prevented the scheduling of the initial mark GC. The
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    83
      // second is that the GC locker may be active and the heap can't be expanded.
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    84
      // In both cases we want to retry the GC so that the initial mark pause is
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    85
      // actually scheduled. In the second case, however, we should stall until
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    86
      // until the GC locker is no longer active and then retry the initial mark GC.
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    87
      _should_retry_gc = true;
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    88
    }
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    89
  }
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    90
  return res;
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    91
}
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
    92
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    93
void VM_G1IncCollectionPause::doit() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    94
  G1CollectedHeap* g1h = G1CollectedHeap::heap();
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
    95
  assert(!_should_initiate_conc_mark ||
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
    96
  ((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
11576
e0bef5ca4602 6976060: G1: humongous object allocations should initiate marking cycles when necessary
brutisso
parents: 10769
diff changeset
    97
   (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent) ||
e0bef5ca4602 6976060: G1: humongous object allocations should initiate marking cycles when necessary
brutisso
parents: 10769
diff changeset
    98
    _gc_cause == GCCause::_g1_humongous_allocation),
e0bef5ca4602 6976060: G1: humongous object allocations should initiate marking cycles when necessary
brutisso
parents: 10769
diff changeset
    99
         "only a GC locker, a System.gc() or a hum allocation induced GC should start a cycle");
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   100
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   101
  if (_word_size > 0) {
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   102
    // An allocation has been requested. So, try to do that first.
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   103
    _result = g1h->attempt_allocation_at_safepoint(_word_size,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   104
                                     false /* expect_null_cur_alloc_region */);
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   105
    if (_result != NULL) {
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   106
      // If we can successfully allocate before we actually do the
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   107
      // pause then we will consider this pause successful.
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   108
      _pause_succeeded = true;
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   109
      return;
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   110
    }
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   111
  }
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   112
4458
075a9ef4e467 6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents: 3261
diff changeset
   113
  GCCauseSetter x(g1h, _gc_cause);
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   114
  if (_should_initiate_conc_mark) {
12934
f9bc0e664918 7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents: 12628
diff changeset
   115
    // It's safer to read old_marking_cycles_completed() here, given
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   116
    // that noone else will be updating it concurrently. Since we'll
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   117
    // only need it if we're initiating a marking cycle, no point in
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   118
    // setting it earlier.
12934
f9bc0e664918 7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents: 12628
diff changeset
   119
    _old_marking_cycles_completed_before = g1h->old_marking_cycles_completed();
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   120
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   121
    // At this point we are supposed to start a concurrent cycle. We
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   122
    // will do so if one is not already in progress.
10523
cdb54c167ab0 7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents: 9996
diff changeset
   123
    bool res = g1h->g1_policy()->force_initial_mark_if_outside_cycle(_gc_cause);
9996
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   124
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   125
    // The above routine returns true if we were able to force the
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   126
    // next GC pause to be an initial mark; it returns false if a
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   127
    // marking cycle is already in progress.
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   128
    //
12227
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   129
    // If a marking cycle is already in progress just return and skip the
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   130
    // pause below - if the reason for requesting this initial mark pause
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   131
    // was due to a System.gc() then the requesting thread should block in
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   132
    // doit_epilogue() until the marking cycle is complete.
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   133
    //
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   134
    // If this initial mark pause was requested as part of a humongous
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   135
    // allocation then we know that the marking cycle must just have
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   136
    // been started by another thread (possibly also allocating a humongous
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   137
    // object) as there was no active marking cycle when the requesting
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   138
    // thread checked before calling collect() in
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   139
    // attempt_allocation_humongous(). Retrying the GC, in this case,
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   140
    // will cause the requesting thread to spin inside collect() until the
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   141
    // just started marking cycle is complete - which may be a while. So
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   142
    // we do NOT retry the GC.
9996
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   143
    if (!res) {
12227
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   144
      assert(_word_size == 0, "Concurrent Full GC/Humongous Object IM shouldn't be allocating");
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   145
      if (_gc_cause != GCCause::_g1_humongous_allocation) {
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   146
        _should_retry_gc = true;
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   147
      }
9996
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   148
      return;
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   149
    }
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   150
  }
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   151
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   152
  _pause_succeeded =
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   153
    g1h->do_collection_pause_at_safepoint(_target_pause_time_ms);
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   154
  if (_pause_succeeded && _word_size > 0) {
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   155
    // An allocation had been requested.
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   156
    _result = g1h->attempt_allocation_at_safepoint(_word_size,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   157
                                      true /* expect_null_cur_alloc_region */);
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   158
  } else {
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   159
    assert(_result == NULL, "invariant");
12227
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   160
    if (!_pause_succeeded) {
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   161
      // Another possible reason reason for the pause to not be successful
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   162
      // is that, again, the GC locker is active (and has become active
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   163
      // since the prologue was executed). In this case we should retry
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   164
      // the pause after waiting for the GC locker to become inactive.
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   165
      _should_retry_gc = true;
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   166
    }
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   167
  }
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   168
}
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   169
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   170
void VM_G1IncCollectionPause::doit_epilogue() {
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   171
  VM_GC_Operation::doit_epilogue();
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   172
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   173
  // If the pause was initiated by a System.gc() and
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   174
  // +ExplicitGCInvokesConcurrent, we have to wait here for the cycle
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   175
  // that just started (or maybe one that was already in progress) to
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   176
  // finish.
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   177
  if (_gc_cause == GCCause::_java_lang_system_gc &&
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   178
      _should_initiate_conc_mark) {
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   179
    assert(ExplicitGCInvokesConcurrent,
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   180
           "the only way to be here is if ExplicitGCInvokesConcurrent is set");
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   181
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   182
    G1CollectedHeap* g1h = G1CollectedHeap::heap();
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   183
12934
f9bc0e664918 7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents: 12628
diff changeset
   184
    // In the doit() method we saved g1h->old_marking_cycles_completed()
f9bc0e664918 7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents: 12628
diff changeset
   185
    // in the _old_marking_cycles_completed_before field. We have to
f9bc0e664918 7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents: 12628
diff changeset
   186
    // wait until we observe that g1h->old_marking_cycles_completed()
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   187
    // has increased by at least one. This can happen if a) we started
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   188
    // a cycle and it completes, b) a cycle already in progress
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   189
    // completes, or c) a Full GC happens.
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   190
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   191
    // If the condition has already been reached, there's no point in
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   192
    // actually taking the lock and doing the wait.
12934
f9bc0e664918 7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents: 12628
diff changeset
   193
    if (g1h->old_marking_cycles_completed() <=
f9bc0e664918 7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents: 12628
diff changeset
   194
                                          _old_marking_cycles_completed_before) {
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   195
      // The following is largely copied from CMS
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   196
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   197
      Thread* thr = Thread::current();
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   198
      assert(thr->is_Java_thread(), "invariant");
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   199
      JavaThread* jt = (JavaThread*)thr;
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   200
      ThreadToNativeFromVM native(jt);
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   201
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   202
      MutexLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
12934
f9bc0e664918 7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents: 12628
diff changeset
   203
      while (g1h->old_marking_cycles_completed() <=
f9bc0e664918 7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents: 12628
diff changeset
   204
                                          _old_marking_cycles_completed_before) {
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   205
        FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag);
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   206
      }
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   207
    }
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   208
  }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   209
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   210
10769
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   211
void VM_CGC_Operation::acquire_pending_list_lock() {
12227
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   212
  assert(_needs_pll, "don't call this otherwise");
10769
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   213
  // The caller may block while communicating
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   214
  // with the SLT thread in order to acquire/release the PLL.
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   215
  ConcurrentMarkThread::slt()->
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   216
    manipulatePLL(SurrogateLockerThread::acquirePLL);
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   217
}
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   218
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   219
void VM_CGC_Operation::release_and_notify_pending_list_lock() {
12227
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   220
  assert(_needs_pll, "don't call this otherwise");
10769
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   221
  // The caller may block while communicating
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   222
  // with the SLT thread in order to acquire/release the PLL.
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   223
  ConcurrentMarkThread::slt()->
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   224
    manipulatePLL(SurrogateLockerThread::releaseAndNotifyPLL);
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   225
}
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   226
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   227
void VM_CGC_Operation::doit() {
12378
ed44b9ecfa2f 7160728: Introduce an extra logging level for G1 logging
brutisso
parents: 12227
diff changeset
   228
  gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
ed44b9ecfa2f 7160728: Introduce an extra logging level for G1 logging
brutisso
parents: 12227
diff changeset
   229
  TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
ed44b9ecfa2f 7160728: Introduce an extra logging level for G1 logging
brutisso
parents: 12227
diff changeset
   230
  TraceTime t(_printGCMessage, G1Log::fine(), true, gclog_or_tty);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   231
  SharedHeap* sh = SharedHeap::heap();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   232
  // This could go away if CollectedHeap gave access to _gc_is_active...
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   233
  if (sh != NULL) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   234
    IsGCActiveMark x;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   235
    _cl->do_void();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   236
  } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   237
    _cl->do_void();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   238
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   239
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   240
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   241
bool VM_CGC_Operation::doit_prologue() {
10769
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   242
  // Note the relative order of the locks must match that in
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   243
  // VM_GC_Operation::doit_prologue() or deadlocks can occur
12227
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   244
  if (_needs_pll) {
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   245
    acquire_pending_list_lock();
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   246
  }
10769
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   247
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   248
  Heap_lock->lock();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   249
  SharedHeap::heap()->_thread_holds_heap_lock_for_gc = true;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   250
  return true;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   251
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   252
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   253
void VM_CGC_Operation::doit_epilogue() {
10769
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   254
  // Note the relative order of the unlocks must match that in
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   255
  // VM_GC_Operation::doit_epilogue()
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   256
  SharedHeap::heap()->_thread_holds_heap_lock_for_gc = false;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   257
  Heap_lock->unlock();
12227
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   258
  if (_needs_pll) {
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   259
    release_and_notify_pending_list_lock();
371690c4f281 7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents: 11576
diff changeset
   260
  }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   261
}