hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
author tonyp
Wed, 25 Jan 2012 12:58:23 -0500
changeset 11584 e1df4d08a1f4
parent 11576 e0bef5ca4602
child 12227 371690c4f281
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
/*
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"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6058
diff changeset
    29
#include "gc_implementation/g1/vm_operations_g1.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6058
diff changeset
    30
#include "gc_implementation/shared/isGCActiveMark.hpp"
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    31
#include "gc_implementation/g1/vm_operations_g1.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6058
diff changeset
    32
#include "runtime/interfaceSupport.hpp"
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    33
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    34
VM_G1CollectForAllocation::VM_G1CollectForAllocation(
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    35
                                                  unsigned int gc_count_before,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    36
                                                  size_t word_size)
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    37
  : VM_G1OperationWithAllocRequest(gc_count_before, word_size) {
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    38
  guarantee(word_size > 0, "an allocation should always be requested");
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    39
}
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    40
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    41
void VM_G1CollectForAllocation::doit() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    42
  G1CollectedHeap* g1h = G1CollectedHeap::heap();
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    43
  _result = g1h->satisfy_failed_allocation(_word_size, &_pause_succeeded);
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    44
  assert(_result == NULL || _pause_succeeded,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    45
         "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
    46
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    47
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    48
void VM_G1CollectFull::doit() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    49
  G1CollectedHeap* g1h = G1CollectedHeap::heap();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    50
  GCCauseSetter x(g1h, _gc_cause);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    51
  g1h->do_full_collection(false /* clear_all_soft_refs */);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    52
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    53
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    54
VM_G1IncCollectionPause::VM_G1IncCollectionPause(
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    55
                                      unsigned int   gc_count_before,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    56
                                      size_t         word_size,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    57
                                      bool           should_initiate_conc_mark,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    58
                                      double         target_pause_time_ms,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    59
                                      GCCause::Cause gc_cause)
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    60
  : VM_G1OperationWithAllocRequest(gc_count_before, word_size),
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    61
    _should_initiate_conc_mark(should_initiate_conc_mark),
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    62
    _target_pause_time_ms(target_pause_time_ms),
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    63
    _full_collections_completed_before(0) {
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    64
  guarantee(target_pause_time_ms > 0.0,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    65
            err_msg("target_pause_time_ms = %1.6lf should be positive",
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    66
                    target_pause_time_ms));
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    67
  guarantee(word_size == 0 || gc_cause == GCCause::_g1_inc_collection_pause,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    68
            "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
    69
            "an incremental GC pause");
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    70
  _gc_cause = gc_cause;
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    71
}
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    72
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    73
void VM_G1IncCollectionPause::doit() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
    74
  G1CollectedHeap* g1h = G1CollectedHeap::heap();
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
    75
  assert(!_should_initiate_conc_mark ||
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
    76
  ((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
11576
e0bef5ca4602 6976060: G1: humongous object allocations should initiate marking cycles when necessary
brutisso
parents: 10769
diff changeset
    77
   (_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
    78
    _gc_cause == GCCause::_g1_humongous_allocation),
e0bef5ca4602 6976060: G1: humongous object allocations should initiate marking cycles when necessary
brutisso
parents: 10769
diff changeset
    79
         "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
    80
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    81
  if (_word_size > 0) {
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    82
    // An allocation has been requested. So, try to do that first.
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    83
    _result = g1h->attempt_allocation_at_safepoint(_word_size,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    84
                                     false /* expect_null_cur_alloc_region */);
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    85
    if (_result != NULL) {
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    86
      // If we can successfully allocate before we actually do the
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    87
      // pause then we will consider this pause successful.
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    88
      _pause_succeeded = true;
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    89
      return;
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    90
    }
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    91
  }
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
    92
4458
075a9ef4e467 6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents: 3261
diff changeset
    93
  GCCauseSetter x(g1h, _gc_cause);
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
    94
  if (_should_initiate_conc_mark) {
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
    95
    // It's safer to read full_collections_completed() here, given
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
    96
    // 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
    97
    // 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
    98
    // setting it earlier.
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
    99
    _full_collections_completed_before = g1h->full_collections_completed();
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   100
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   101
    // 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
   102
    // 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
   103
    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
   104
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   105
    // 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
   106
    // 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
   107
    // marking cycle is already in progress.
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   108
    //
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   109
    // If a marking cycle is already in progress just return and skip
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   110
    // the pause - the requesting thread should block in doit_epilogue
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   111
    // until the marking cycle is complete.
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   112
    if (!res) {
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   113
      assert(_word_size == 0, "ExplicitGCInvokesConcurrent shouldn't be allocating");
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   114
      return;
3851e45f93e7 7045751: G1: +ExplicitGCInvokesConcurrent causes excessive single region evacuation pauses
johnc
parents: 8921
diff changeset
   115
    }
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   116
  }
7398
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   117
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   118
  _pause_succeeded =
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   119
    g1h->do_collection_pause_at_safepoint(_target_pause_time_ms);
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   120
  if (_pause_succeeded && _word_size > 0) {
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   121
    // An allocation had been requested.
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   122
    _result = g1h->attempt_allocation_at_safepoint(_word_size,
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   123
                                      true /* expect_null_cur_alloc_region */);
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   124
  } else {
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   125
    assert(_result == NULL, "invariant");
e4aa6d9bda09 6974966: G1: unnecessary direct-to-old allocations
tonyp
parents: 7397
diff changeset
   126
  }
6058
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   127
}
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   128
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   129
void VM_G1IncCollectionPause::doit_epilogue() {
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   130
  VM_GC_Operation::doit_epilogue();
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   131
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   132
  // 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
   133
  // +ExplicitGCInvokesConcurrent, we have to wait here for the cycle
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   134
  // 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
   135
  // finish.
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   136
  if (_gc_cause == GCCause::_java_lang_system_gc &&
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   137
      _should_initiate_conc_mark) {
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   138
    assert(ExplicitGCInvokesConcurrent,
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   139
           "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
   140
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   141
    G1CollectedHeap* g1h = G1CollectedHeap::heap();
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   142
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   143
    // In the doit() method we saved g1h->full_collections_completed()
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   144
    // in the _full_collections_completed_before field. We have to
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   145
    // wait until we observe that g1h->full_collections_completed()
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   146
    // 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
   147
    // 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
   148
    // completes, or c) a Full GC happens.
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   149
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   150
    // 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
   151
    // actually taking the lock and doing the wait.
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   152
    if (g1h->full_collections_completed() <=
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   153
                                          _full_collections_completed_before) {
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   154
      // The following is largely copied from CMS
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   155
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   156
      Thread* thr = Thread::current();
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   157
      assert(thr->is_Java_thread(), "invariant");
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   158
      JavaThread* jt = (JavaThread*)thr;
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   159
      ThreadToNativeFromVM native(jt);
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   160
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   161
      MutexLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   162
      while (g1h->full_collections_completed() <=
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   163
                                          _full_collections_completed_before) {
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   164
        FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag);
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   165
      }
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   166
    }
9c9aec6ab47d 6944166: G1: explicit GCs are not always handled correctly
tonyp
parents: 5547
diff changeset
   167
  }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   168
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   169
10769
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   170
void VM_CGC_Operation::acquire_pending_list_lock() {
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   171
  // 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
   172
  // 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
   173
  ConcurrentMarkThread::slt()->
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   174
    manipulatePLL(SurrogateLockerThread::acquirePLL);
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   175
}
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   176
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   177
void VM_CGC_Operation::release_and_notify_pending_list_lock() {
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   178
  // 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
   179
  // 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
   180
  ConcurrentMarkThread::slt()->
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   181
    manipulatePLL(SurrogateLockerThread::releaseAndNotifyPLL);
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   182
}
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   183
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   184
void VM_CGC_Operation::doit() {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   185
  gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   186
  TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   187
  TraceTime t(_printGCMessage, PrintGC, true, gclog_or_tty);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   188
  SharedHeap* sh = SharedHeap::heap();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   189
  // 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
   190
  if (sh != NULL) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   191
    IsGCActiveMark x;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   192
    _cl->do_void();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   193
  } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   194
    _cl->do_void();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   195
  }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   196
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   197
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   198
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
   199
  // 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
   200
  // VM_GC_Operation::doit_prologue() or deadlocks can occur
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   201
  acquire_pending_list_lock();
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   202
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   203
  Heap_lock->lock();
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   204
  SharedHeap::heap()->_thread_holds_heap_lock_for_gc = true;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   205
  return true;
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
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
   209
  // 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
   210
  // VM_GC_Operation::doit_epilogue()
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   211
  SharedHeap::heap()->_thread_holds_heap_lock_for_gc = false;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   212
  Heap_lock->unlock();
10769
983d377770fd 7099824: G1: we should take the pending list lock before doing the remark pause
johnc
parents: 10523
diff changeset
   213
  release_and_notify_pending_list_lock();
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents:
diff changeset
   214
}