hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
author johnc
Thu, 22 Sep 2011 10:57:37 -0700
changeset 10670 4ea0e7d2ffbc
parent 10240 c3931827e0cf
child 11174 fccee5238e70
permissions -rw-r--r--
6484982: G1: process references during evacuation pauses Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate. Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
8684
7ebbd0b3e295 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 8296
diff changeset
     2
 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5434
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5434
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: 5434
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    26
#include "classfile/symbolTable.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    27
#include "classfile/systemDictionary.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    28
#include "code/codeCache.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    29
#include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    30
#include "gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    31
#include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    32
#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    33
#include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    34
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    35
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    36
#include "gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    37
#include "gc_implementation/parNew/parNewGeneration.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    38
#include "gc_implementation/shared/collectorCounters.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    39
#include "gc_implementation/shared/isGCActiveMark.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    40
#include "gc_interface/collectedHeap.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    41
#include "memory/cardTableRS.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    42
#include "memory/collectorPolicy.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    43
#include "memory/gcLocker.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    44
#include "memory/genCollectedHeap.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    45
#include "memory/genMarkSweep.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    46
#include "memory/genOopClosures.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    47
#include "memory/iterator.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    48
#include "memory/referencePolicy.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    49
#include "memory/resourceArea.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    50
#include "oops/oop.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    51
#include "prims/jvmtiExport.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    52
#include "runtime/globals_extension.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    53
#include "runtime/handles.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    54
#include "runtime/java.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    55
#include "runtime/vmThread.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    56
#include "services/memoryService.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6985
diff changeset
    57
#include "services/runtimeService.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
// statics
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
CMSCollector* ConcurrentMarkSweepGeneration::_collector = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
bool          CMSCollector::_full_gc_requested          = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
// In support of CMS/VM thread synchronization
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
// We split use of the CGC_lock into 2 "levels".
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
// The low-level locking is of the usual CGC_lock monitor. We introduce
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
// a higher level "token" (hereafter "CMS token") built on top of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
// low level monitor (hereafter "CGC lock").
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
// The token-passing protocol gives priority to the VM thread. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
// CMS-lock doesn't provide any fairness guarantees, but clients
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
// should ensure that it is only held for very short, bounded
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
// durations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
// When either of the CMS thread or the VM thread is involved in
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
// collection operations during which it does not want the other
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
// thread to interfere, it obtains the CMS token.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
// If either thread tries to get the token while the other has
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
// it, that thread waits. However, if the VM thread and CMS thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
// both want the token, then the VM thread gets priority while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
// CMS thread waits. This ensures, for instance, that the "concurrent"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
// phases of the CMS thread's work do not block out the VM thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
// for long periods of time as the CMS thread continues to hog
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
// the token. (See bug 4616232).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
// The baton-passing functions are, however, controlled by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
// flags _foregroundGCShouldWait and _foregroundGCIsActive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
// and here the low-level CMS lock, not the high level token,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
// ensures mutual exclusion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
// Two important conditions that we have to satisfy:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
// 1. if a thread does a low-level wait on the CMS lock, then it
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
//    relinquishes the CMS token if it were holding that token
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
//    when it acquired the low-level CMS lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
// 2. any low-level notifications on the low-level lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
//    should only be sent when a thread has relinquished the token.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
// In the absence of either property, we'd have potential deadlock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
// We protect each of the CMS (concurrent and sequential) phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
// with the CMS _token_, not the CMS _lock_.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
// The only code protected by CMS lock is the token acquisition code
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
// itself, see ConcurrentMarkSweepThread::[de]synchronize(), and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
// baton-passing code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
// Unfortunately, i couldn't come up with a good abstraction to factor and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
// hide the naked CGC_lock manipulation in the baton-passing code
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
// further below. That's something we should try to do. Also, the proof
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
// of correctness of this 2-level locking scheme is far from obvious,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
// and potentially quite slippery. We have an uneasy supsicion, for instance,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
// that there may be a theoretical possibility of delay/starvation in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
// low-level lock/wait/notify scheme used for the baton-passing because of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
// potential intereference with the priority scheme embodied in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
// CMS-token-passing protocol. See related comments at a CGC_lock->wait()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
// invocation further below and marked with "XXX 20011219YSR".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
// Indeed, as we note elsewhere, this may become yet more slippery
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
// in the presence of multiple CMS and/or multiple VM threads. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
class CMSTokenSync: public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  bool _is_cms_thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  CMSTokenSync(bool is_cms_thread):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
    _is_cms_thread(is_cms_thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
    assert(is_cms_thread == Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
           "Incorrect argument to constructor");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
    ConcurrentMarkSweepThread::synchronize(_is_cms_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  ~CMSTokenSync() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
    assert(_is_cms_thread ?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
             ConcurrentMarkSweepThread::cms_thread_has_cms_token() :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
             ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
          "Incorrect state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
    ConcurrentMarkSweepThread::desynchronize(_is_cms_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
// Convenience class that does a CMSTokenSync, and then acquires
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
// upto three locks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
class CMSTokenSyncWithLocks: public CMSTokenSync {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  // Note: locks are acquired in textual declaration order
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  // and released in the opposite order
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  MutexLockerEx _locker1, _locker2, _locker3;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  CMSTokenSyncWithLocks(bool is_cms_thread, Mutex* mutex1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
                        Mutex* mutex2 = NULL, Mutex* mutex3 = NULL):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    CMSTokenSync(is_cms_thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
    _locker1(mutex1, Mutex::_no_safepoint_check_flag),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
    _locker2(mutex2, Mutex::_no_safepoint_check_flag),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
    _locker3(mutex3, Mutex::_no_safepoint_check_flag)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
// Wrapper class to temporarily disable icms during a foreground cms collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
class ICMSDisabler: public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  // The ctor disables icms and wakes up the thread so it notices the change;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  // the dtor re-enables icms.  Note that the CMSCollector methods will check
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  // CMSIncrementalMode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  ICMSDisabler()  { CMSCollector::disable_icms(); CMSCollector::start_icms(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  ~ICMSDisabler() { CMSCollector::enable_icms(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
//  Concurrent Mark-Sweep Generation /////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
NOT_PRODUCT(CompactibleFreeListSpace* debug_cms_space;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
// This struct contains per-thread things necessary to support parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
// young-gen collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
class CMSParGCThreadState: public CHeapObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  CFLS_LAB lab;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  PromotionInfo promo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  // Constructor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  CMSParGCThreadState(CompactibleFreeListSpace* cfls) : lab(cfls) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
    promo.setSpace(cfls);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
     ReservedSpace rs, size_t initial_byte_size, int level,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
     CardTableRS* ct, bool use_adaptive_freelists,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
     FreeBlockDictionary::DictionaryChoice dictionaryChoice) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  CardGeneration(rs, initial_byte_size, level, ct),
5694
1e0532a6abff 6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents: 5434
diff changeset
   193
  _dilatation_factor(((double)MinChunkSize)/((double)(CollectedHeap::min_fill_size()))),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  _debug_collection_type(Concurrent_collection_type)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  HeapWord* bottom = (HeapWord*) _virtual_space.low();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  HeapWord* end    = (HeapWord*) _virtual_space.high();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  _direct_allocated_words = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
    _numObjectsPromoted = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
    _numWordsPromoted = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
    _numObjectsAllocated = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
    _numWordsAllocated = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  _cmsSpace = new CompactibleFreeListSpace(_bts, MemRegion(bottom, end),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
                                           use_adaptive_freelists,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
                                           dictionaryChoice);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  NOT_PRODUCT(debug_cms_space = _cmsSpace;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  if (_cmsSpace == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
    vm_exit_during_initialization(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
      "CompactibleFreeListSpace allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  _cmsSpace->_gen = this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
  _gc_stats = new CMSGCStats();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  // Verify the assumption that FreeChunk::_prev and OopDesc::_klass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  // offsets match. The ability to tell free chunks from objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  // depends on this property.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
  debug_only(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
    FreeChunk* junk = NULL;
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
   224
    assert(UseCompressedOops ||
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
   225
           junk->prev_addr() == (void*)(oop(junk)->klass_addr()),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
           "Offset of FreeChunk::_prev within FreeChunk must match"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
           "  that of OopDesc::_klass within OopDesc");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  )
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
   229
  if (CollectedHeap::use_parallel_gc_threads()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
    typedef CMSParGCThreadState* CMSParGCThreadStatePtr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
    _par_gc_thread_states =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
      NEW_C_HEAP_ARRAY(CMSParGCThreadStatePtr, ParallelGCThreads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
    if (_par_gc_thread_states == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
      vm_exit_during_initialization("Could not allocate par gc structs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
    for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
      _par_gc_thread_states[i] = new CMSParGCThreadState(cmsSpace());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
      if (_par_gc_thread_states[i] == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
        vm_exit_during_initialization("Could not allocate par gc structs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
    _par_gc_thread_states = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  _incremental_collection_failed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  // The "dilatation_factor" is the expansion that can occur on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
  // account of the fact that the minimum object size in the CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  // generation may be larger than that in, say, a contiguous young
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  //  generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  // Ideally, in the calculation below, we'd compute the dilatation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  // factor as: MinChunkSize/(promoting_gen's min object size)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  // Since we do not have such a general query interface for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  // promoting generation, we'll instead just use the mimimum
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  // object size (which today is a header's worth of space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  // note that all arithmetic is in units of HeapWords.
5694
1e0532a6abff 6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents: 5434
diff changeset
   256
  assert(MinChunkSize >= CollectedHeap::min_fill_size(), "just checking");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  assert(_dilatation_factor >= 1.0, "from previous assert");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   260
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   261
// The field "_initiating_occupancy" represents the occupancy percentage
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   262
// at which we trigger a new collection cycle.  Unless explicitly specified
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   263
// via CMSInitiating[Perm]OccupancyFraction (argument "io" below), it
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   264
// is calculated by:
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   265
//
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   266
//   Let "f" be MinHeapFreeRatio in
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   267
//
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   268
//    _intiating_occupancy = 100-f +
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   269
//                           f * (CMSTrigger[Perm]Ratio/100)
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   270
//   where CMSTrigger[Perm]Ratio is the argument "tr" below.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   271
//
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   272
// That is, if we assume the heap is at its desired maximum occupancy at the
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   273
// end of a collection, we let CMSTrigger[Perm]Ratio of the (purported) free
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   274
// space be allocated before initiating a new collection cycle.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   275
//
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   276
void ConcurrentMarkSweepGeneration::init_initiating_occupancy(intx io, intx tr) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   277
  assert(io <= 100 && tr >= 0 && tr <= 100, "Check the arguments");
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   278
  if (io >= 0) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   279
    _initiating_occupancy = (double)io / 100.0;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   280
  } else {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   281
    _initiating_occupancy = ((100 - MinHeapFreeRatio) +
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   282
                             (double)(tr * MinHeapFreeRatio) / 100.0)
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   283
                            / 100.0;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   284
  }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   285
}
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   286
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
void ConcurrentMarkSweepGeneration::ref_processor_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  assert(collector() != NULL, "no collector");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  collector()->ref_processor_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
void CMSCollector::ref_processor_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  if (_ref_processor == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
    // Allocate and initialize a reference processor
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
   295
    _ref_processor =
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
   296
      new ReferenceProcessor(_span,                               // span
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
   297
                             (ParallelGCThreads > 1) && ParallelRefProcEnabled, // mt processing
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
   298
                             (int) ParallelGCThreads,             // mt processing degree
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
   299
                             _cmsGen->refs_discovery_is_mt(),     // mt discovery
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
   300
                             (int) MAX2(ConcGCThreads, ParallelGCThreads), // mt discovery degree
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
   301
                             _cmsGen->refs_discovery_is_atomic(), // discovery is not atomic
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
   302
                             &_is_alive_closure,                  // closure for liveness info
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
   303
                             false);                              // next field updates do not need write barrier
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
    // Initialize the _ref_processor field of CMSGen
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
    _cmsGen->set_ref_processor(_ref_processor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
    // Allocate a dummy ref processor for perm gen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
    ReferenceProcessor* rp2 = new ReferenceProcessor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
    if (rp2 == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
      vm_exit_during_initialization("Could not allocate ReferenceProcessor object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
    _permGen->set_ref_processor(rp2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
CMSAdaptiveSizePolicy* CMSCollector::size_policy() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
    "Wrong type of heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  CMSAdaptiveSizePolicy* sp = (CMSAdaptiveSizePolicy*)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
    gch->gen_policy()->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
  assert(sp->is_gc_cms_adaptive_size_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
    "Wrong type of size policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  return sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
CMSGCAdaptivePolicyCounters* CMSCollector::gc_adaptive_policy_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  CMSGCAdaptivePolicyCounters* results =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
    (CMSGCAdaptivePolicyCounters*) collector_policy()->counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  assert(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
    results->kind() == GCPolicyCounters::CMSGCAdaptivePolicyCountersKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    "Wrong gc policy counter kind");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  return results;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
void ConcurrentMarkSweepGeneration::initialize_performance_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  const char* gen_name = "old";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  // Generation Counters - generation 1, 1 subspace
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  _gen_counters = new GenerationCounters(gen_name, 1, 1, &_virtual_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  _space_counters = new GSpaceCounters(gen_name, 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
                                       _virtual_space.reserved_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
                                       this, _gen_counters);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
CMSStats::CMSStats(ConcurrentMarkSweepGeneration* cms_gen, unsigned int alpha):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  _cms_gen(cms_gen)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  assert(alpha <= 100, "bad value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  _saved_alpha = alpha;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  // Initialize the alphas to the bootstrap value of 100.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  _gc0_alpha = _cms_alpha = 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  _cms_begin_time.update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
  _cms_end_time.update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
  _gc0_duration = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
  _gc0_period = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  _gc0_promoted = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
  _cms_duration = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
  _cms_period = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
  _cms_allocated = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
  _cms_used_at_gc0_begin = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
  _cms_used_at_gc0_end = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
  _allow_duty_cycle_reduction = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  _valid_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
  _icms_duty_cycle = CMSIncrementalDutyCycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   376
double CMSStats::cms_free_adjustment_factor(size_t free) const {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   377
  // TBD: CR 6909490
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   378
  return 1.0;
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   379
}
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   380
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   381
void CMSStats::adjust_cms_free_adjustment_factor(bool fail, size_t free) {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   382
}
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   383
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
// If promotion failure handling is on use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
// the padded average size of the promotion for each
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
// young generation collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
double CMSStats::time_until_cms_gen_full() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  size_t cms_free = _cms_gen->cmsSpace()->free();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  GenCollectedHeap* gch = GenCollectedHeap::heap();
6985
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
   390
  size_t expected_promotion = MIN2(gch->get_gen(0)->capacity(),
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
   391
                                   (size_t) _cms_gen->gc_stats()->avg_promoted()->padded_average());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  if (cms_free > expected_promotion) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
    // Start a cms collection if there isn't enough space to promote
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
    // for the next minor collection.  Use the padded average as
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
    // a safety factor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
    cms_free -= expected_promotion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
    // Adjust by the safety factor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
    double cms_free_dbl = (double)cms_free;
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   400
    double cms_adjustment = (100.0 - CMSIncrementalSafetyFactor)/100.0;
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   401
    // Apply a further correction factor which tries to adjust
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   402
    // for recent occurance of concurrent mode failures.
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   403
    cms_adjustment = cms_adjustment * cms_free_adjustment_factor(cms_free);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   404
    cms_free_dbl = cms_free_dbl * cms_adjustment;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
      gclog_or_tty->print_cr("CMSStats::time_until_cms_gen_full: cms_free "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
        SIZE_FORMAT " expected_promotion " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
        cms_free, expected_promotion);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
      gclog_or_tty->print_cr("  cms_free_dbl %f cms_consumption_rate %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
        cms_free_dbl, cms_consumption_rate() + 1.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
    // Add 1 in case the consumption rate goes to zero.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
    return cms_free_dbl / (cms_consumption_rate() + 1.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  return 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
// Compare the duration of the cms collection to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
// time remaining before the cms generation is empty.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
// Note that the time from the start of the cms collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
// to the start of the cms sweep (less than the total
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
// duration of the cms collection) can be used.  This
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
// has been tried and some applications experienced
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
// promotion failures early in execution.  This was
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
// possibly because the averages were not accurate
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
// enough at the beginning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
double CMSStats::time_until_cms_start() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  // We add "gc0_period" to the "work" calculation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
  // below because this query is done (mostly) at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  // end of a scavenge, so we need to conservatively
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  // account for that much possible delay
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  // in the query so as to avoid concurrent mode failures
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  // due to starting the collection just a wee bit too
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  // late.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  double work = cms_duration() + gc0_period();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
  double deadline = time_until_cms_gen_full();
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   438
  // If a concurrent mode failure occurred recently, we want to be
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   439
  // more conservative and halve our expected time_until_cms_gen_full()
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  if (work > deadline) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
      gclog_or_tty->print(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
        " CMSCollector: collect because of anticipated promotion "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
        "before full %3.7f + %3.7f > %3.7f ", cms_duration(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
        gc0_period(), time_until_cms_gen_full());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
    return 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  return work - deadline;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
// Return a duty cycle based on old_duty_cycle and new_duty_cycle, limiting the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
// amount of change to prevent wild oscillation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
unsigned int CMSStats::icms_damped_duty_cycle(unsigned int old_duty_cycle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
                                              unsigned int new_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  assert(old_duty_cycle <= 100, "bad input value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  assert(new_duty_cycle <= 100, "bad input value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  // Note:  use subtraction with caution since it may underflow (values are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
  // unsigned).  Addition is safe since we're in the range 0-100.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  unsigned int damped_duty_cycle = new_duty_cycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
  if (new_duty_cycle < old_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
    const unsigned int largest_delta = MAX2(old_duty_cycle / 4, 5U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
    if (new_duty_cycle + largest_delta < old_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
      damped_duty_cycle = old_duty_cycle - largest_delta;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  } else if (new_duty_cycle > old_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
    const unsigned int largest_delta = MAX2(old_duty_cycle / 4, 15U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
    if (new_duty_cycle > old_duty_cycle + largest_delta) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
      damped_duty_cycle = MIN2(old_duty_cycle + largest_delta, 100U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  assert(damped_duty_cycle <= 100, "invalid duty cycle computed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
  if (CMSTraceIncrementalPacing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
    gclog_or_tty->print(" [icms_damped_duty_cycle(%d,%d) = %d] ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
                           old_duty_cycle, new_duty_cycle, damped_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  return damped_duty_cycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
unsigned int CMSStats::icms_update_duty_cycle_impl() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  assert(CMSIncrementalPacing && valid(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
         "should be handled in icms_update_duty_cycle()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
  double cms_time_so_far = cms_timer().seconds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
  double scaled_duration = cms_duration_per_mb() * _cms_used_at_gc0_end / M;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
  double scaled_duration_remaining = fabsd(scaled_duration - cms_time_so_far);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  // Avoid division by 0.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  double time_until_full = MAX2(time_until_cms_gen_full(), 0.01);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
  double duty_cycle_dbl = 100.0 * scaled_duration_remaining / time_until_full;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
  unsigned int new_duty_cycle = MIN2((unsigned int)duty_cycle_dbl, 100U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
  if (new_duty_cycle > _icms_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
    // Avoid very small duty cycles (1 or 2); 0 is allowed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
    if (new_duty_cycle > 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
      _icms_duty_cycle = icms_damped_duty_cycle(_icms_duty_cycle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
                                                new_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
  } else if (_allow_duty_cycle_reduction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
    // The duty cycle is reduced only once per cms cycle (see record_cms_end()).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
    new_duty_cycle = icms_damped_duty_cycle(_icms_duty_cycle, new_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
    // Respect the minimum duty cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
    unsigned int min_duty_cycle = (unsigned int)CMSIncrementalDutyCycleMin;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
    _icms_duty_cycle = MAX2(new_duty_cycle, min_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  if (PrintGCDetails || CMSTraceIncrementalPacing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
    gclog_or_tty->print(" icms_dc=%d ", _icms_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  _allow_duty_cycle_reduction = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  return _icms_duty_cycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
void CMSStats::print_on(outputStream *st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  st->print(" gc0_alpha=%d,cms_alpha=%d", _gc0_alpha, _cms_alpha);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  st->print(",gc0_dur=%g,gc0_per=%g,gc0_promo=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
               gc0_duration(), gc0_period(), gc0_promoted());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  st->print(",cms_dur=%g,cms_dur_per_mb=%g,cms_per=%g,cms_alloc=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
            cms_duration(), cms_duration_per_mb(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
            cms_period(), cms_allocated());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  st->print(",cms_since_beg=%g,cms_since_end=%g",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
            cms_time_since_begin(), cms_time_since_end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  st->print(",cms_used_beg=" SIZE_FORMAT ",cms_used_end=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
            _cms_used_at_gc0_begin, _cms_used_at_gc0_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  if (CMSIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
    st->print(",dc=%d", icms_duty_cycle());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  if (valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    st->print(",promo_rate=%g,cms_alloc_rate=%g",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
              promotion_rate(), cms_allocation_rate());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
    st->print(",cms_consumption_rate=%g,time_until_full=%g",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
              cms_consumption_rate(), time_until_cms_gen_full());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
  st->print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
#endif // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
CMSCollector::CollectorState CMSCollector::_collectorState =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
                             CMSCollector::Idling;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
bool CMSCollector::_foregroundGCIsActive = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
bool CMSCollector::_foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
                           ConcurrentMarkSweepGeneration* permGen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
                           CardTableRS*                   ct,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
                           ConcurrentMarkSweepPolicy*     cp):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  _cmsGen(cmsGen),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
  _permGen(permGen),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
  _ct(ct),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  _ref_processor(NULL),    // will be set later
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
  _conc_workers(NULL),     // may be set later
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
  _abort_preclean(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
  _start_sampling(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  _between_prologue_and_epilogue(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  _markBitMap(0, Mutex::leaf + 1, "CMS_markBitMap_lock"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
  _perm_gen_verify_bit_map(0, -1 /* no mutex */, "No_lock"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
  _modUnionTable((CardTableModRefBS::card_shift - LogHeapWordSize),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
                 -1 /* lock-free */, "No_lock" /* dummy */),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
  _modUnionClosure(&_modUnionTable),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  _modUnionClosurePar(&_modUnionTable),
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   566
  // Adjust my span to cover old (cms) gen and perm gen
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   567
  _span(cmsGen->reserved()._union(permGen->reserved())),
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   568
  // Construct the is_alive_closure with _span & markBitMap
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   569
  _is_alive_closure(_span, &_markBitMap),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
  _restart_addr(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
  _overflow_list(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
  _stats(cmsGen),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
  _eden_chunk_array(NULL),     // may be set in ctor body
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
  _eden_chunk_capacity(0),     // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
  _eden_chunk_index(0),        // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
  _survivor_plab_array(NULL),  // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
  _survivor_chunk_array(NULL), // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  _survivor_chunk_capacity(0), // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  _survivor_chunk_index(0),    // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  _ser_pmc_preclean_ovflw(0),
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
   581
  _ser_kac_preclean_ovflw(0),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  _ser_pmc_remark_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
  _par_pmc_remark_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
  _ser_kac_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
  _par_kac_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
  _num_par_pushes(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
  _collection_count_start(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
  _verifying(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  _icms_start_limit(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
  _icms_stop_limit(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  _verification_mark_bm(0, Mutex::leaf + 1, "CMS_verification_mark_bm_lock"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
  _completed_initialization(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  _collector_policy(cp),
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   596
  _should_unload_classes(false),
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   597
  _concurrent_cycles_since_last_unload(0),
2885
7dd49b9daa4a 6848641: CMSCollector::_roots_scanning_options should be initialized
ysr
parents: 2346
diff changeset
   598
  _roots_scanning_options(0),
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   599
  _inter_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   600
  _intra_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
  if (ExplicitGCInvokesConcurrentAndUnloadsClasses) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
    ExplicitGCInvokesConcurrent = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
  // Now expand the span and allocate the collection support structures
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
  // (MUT, marking bit map etc.) to cover both generations subject to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
  // collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
  // First check that _permGen is adjacent to _cmsGen and above it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
  assert(   _cmsGen->reserved().word_size()  > 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
         && _permGen->reserved().word_size() > 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
         "generations should not be of zero size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
  assert(_cmsGen->reserved().intersection(_permGen->reserved()).is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
         "_cmsGen and _permGen should not overlap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
  assert(_cmsGen->reserved().end() == _permGen->reserved().start(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
         "_cmsGen->end() different from _permGen->start()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  // For use by dirty card to oop closures.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
  _cmsGen->cmsSpace()->set_collector(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
  _permGen->cmsSpace()->set_collector(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
  // Allocate MUT and marking bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
    MutexLockerEx x(_markBitMap.lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
    if (!_markBitMap.allocate(_span)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
      warning("Failed to allocate CMS Bit Map");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
    assert(_markBitMap.covers(_span), "_markBitMap inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
    _modUnionTable.allocate(_span);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
    assert(_modUnionTable.covers(_span), "_modUnionTable inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   636
  if (!_markStack.allocate(MarkStackSize)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
    warning("Failed to allocate CMS Marking Stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
  if (!_revisitStack.allocate(CMSRevisitStackSize)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
    warning("Failed to allocate CMS Revisit Stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
  // Support for multi-threaded concurrent phases
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
   646
  if (CMSConcurrentMTEnabled) {
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   647
    if (FLAG_IS_DEFAULT(ConcGCThreads)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
      // just for now
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   649
      FLAG_SET_DEFAULT(ConcGCThreads, (ParallelGCThreads + 3)/4);
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   650
    }
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   651
    if (ConcGCThreads > 1) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
      _conc_workers = new YieldingFlexibleWorkGang("Parallel CMS Threads",
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   653
                                 ConcGCThreads, true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
      if (_conc_workers == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
        warning("GC/CMS: _conc_workers allocation failure: "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
              "forcing -CMSConcurrentMTEnabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
        CMSConcurrentMTEnabled = false;
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
   658
      } else {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
   659
        _conc_workers->initialize_workers();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
      CMSConcurrentMTEnabled = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
  if (!CMSConcurrentMTEnabled) {
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   666
    ConcGCThreads = 0;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
    // Turn off CMSCleanOnEnter optimization temporarily for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
    // the MT case where it's not fixed yet; see 6178663.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
    CMSCleanOnEnter = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
  }
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   672
  assert((_conc_workers != NULL) == (ConcGCThreads > 1),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
         "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
  // Parallel task queues; these are shared for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
  // concurrent and stop-world phases of CMS, but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
  // are not shared with parallel scavenge (ParNew).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
    uint i;
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   680
    uint num_queues = (uint) MAX2(ParallelGCThreads, ConcGCThreads);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
    if ((CMSParallelRemarkEnabled || CMSConcurrentMTEnabled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
         || ParallelRefProcEnabled)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
        && num_queues > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
      _task_queues = new OopTaskQueueSet(num_queues);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
      if (_task_queues == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
        warning("task_queues allocation failure.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
      _hash_seed = NEW_C_HEAP_ARRAY(int, num_queues);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
      if (_hash_seed == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
        warning("_hash_seed array allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
6067
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5702
diff changeset
   696
      typedef Padded<OopTaskQueue> PaddedOopTaskQueue;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
      for (i = 0; i < num_queues; i++) {
6067
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5702
diff changeset
   698
        PaddedOopTaskQueue *q = new PaddedOopTaskQueue();
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5702
diff changeset
   699
        if (q == NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
          warning("work_queue allocation failure.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
        }
6067
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5702
diff changeset
   703
        _task_queues->register_queue(i, q);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
      for (i = 0; i < num_queues; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
        _task_queues->queue(i)->initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
        _hash_seed[i] = 17;  // copied from ParNew
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   712
  _cmsGen ->init_initiating_occupancy(CMSInitiatingOccupancyFraction, CMSTriggerRatio);
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   713
  _permGen->init_initiating_occupancy(CMSInitiatingPermOccupancyFraction, CMSTriggerPermRatio);
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   714
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
  // Clip CMSBootstrapOccupancy between 0 and 100.
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   716
  _bootstrap_occupancy = ((double)MIN2((uintx)100, MAX2((uintx)0, CMSBootstrapOccupancy)))
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
                         /(double)100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
  _full_gcs_since_conc_gc = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
  // Now tell CMS generations the identity of their collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
  ConcurrentMarkSweepGeneration::set_collector(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
  // Create & start a CMS thread for this CMS collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
  _cmsThread = ConcurrentMarkSweepThread::start(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
  assert(cmsThread() != NULL, "CMS Thread should have been created");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
  assert(cmsThread()->collector() == this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
         "CMS Thread should refer to this gen");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
  assert(CGC_lock != NULL, "Where's the CGC_lock?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
  // Support for parallelizing young gen rescan
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
  _young_gen = gch->prev_gen(_cmsGen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
  if (gch->supports_inline_contig_alloc()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
    _top_addr = gch->top_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
    _end_addr = gch->end_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
    assert(_young_gen != NULL, "no _young_gen");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
    _eden_chunk_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
    _eden_chunk_capacity = (_young_gen->max_capacity()+CMSSamplingGrain)/CMSSamplingGrain;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
    _eden_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, _eden_chunk_capacity);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
    if (_eden_chunk_array == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
      _eden_chunk_capacity = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
      warning("GC/CMS: _eden_chunk_array allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
  assert(_eden_chunk_array != NULL || _eden_chunk_capacity == 0, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
  // Support for parallelizing survivor space rescan
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
  if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
5040
529add9be0d5 6910182: CMS: assert(_cursor[j] == _survivor_plab_array[j].end(),"Ctl pt invariant")
jmasa
parents: 5035
diff changeset
   750
    const size_t max_plab_samples =
529add9be0d5 6910182: CMS: assert(_cursor[j] == _survivor_plab_array[j].end(),"Ctl pt invariant")
jmasa
parents: 5035
diff changeset
   751
      ((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize;
529add9be0d5 6910182: CMS: assert(_cursor[j] == _survivor_plab_array[j].end(),"Ctl pt invariant")
jmasa
parents: 5035
diff changeset
   752
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
    _survivor_plab_array  = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
    _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
    _cursor               = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
    if (_survivor_plab_array == NULL || _survivor_chunk_array == NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
        || _cursor == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
      warning("Failed to allocate survivor plab/chunk array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
      if (_survivor_plab_array  != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
        FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
        _survivor_plab_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
      if (_survivor_chunk_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
        FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
        _survivor_chunk_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
      if (_cursor != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
        FREE_C_HEAP_ARRAY(size_t, _cursor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
        _cursor = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
      _survivor_chunk_capacity = 2*max_plab_samples;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
      for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
        HeapWord** vec = NEW_C_HEAP_ARRAY(HeapWord*, max_plab_samples);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
        if (vec == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
          warning("Failed to allocate survivor plab array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
          for (int j = i; j > 0; j--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
            FREE_C_HEAP_ARRAY(HeapWord*, _survivor_plab_array[j-1].array());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
          FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
          FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
          _survivor_plab_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
          _survivor_chunk_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
          _survivor_chunk_capacity = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
          ChunkArray* cur =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
            ::new (&_survivor_plab_array[i]) ChunkArray(vec,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
                                                        max_plab_samples);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
          assert(cur->end() == 0, "Should be 0");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
          assert(cur->array() == vec, "Should be vec");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
          assert(cur->capacity() == max_plab_samples, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
  assert(   (   _survivor_plab_array  != NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
             && _survivor_chunk_array != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
         || (   _survivor_chunk_capacity == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
             && _survivor_chunk_index == 0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
         "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
  // Choose what strong roots should be scanned depending on verification options
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
  // and perm gen collection mode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
  if (!CMSClassUnloadingEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
    // If class unloading is disabled we want to include all classes into the root set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
    add_root_scanning_option(SharedHeap::SO_AllClasses);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
    add_root_scanning_option(SharedHeap::SO_SystemClasses);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
  NOT_PRODUCT(_overflow_counter = CMSMarkStackOverflowInterval;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
  _gc_counters = new CollectorCounters("CMS", 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
  _completed_initialization = true;
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   815
  _inter_sweep_timer.start();  // start of time
5431
5c4054a50dbb 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 5343
diff changeset
   816
#ifdef SPARC
5c4054a50dbb 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 5343
diff changeset
   817
  // Issue a stern warning, but allow use for experimentation and debugging.
5c4054a50dbb 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 5343
diff changeset
   818
  if (VM_Version::is_sun4v() && UseMemSetInBOT) {
5c4054a50dbb 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 5343
diff changeset
   819
    assert(!FLAG_IS_DEFAULT(UseMemSetInBOT), "Error");
5c4054a50dbb 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 5343
diff changeset
   820
    warning("Experimental flag -XX:+UseMemSetInBOT is known to cause instability"
5c4054a50dbb 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 5343
diff changeset
   821
            " on sun4v; please understand that you are using at your own risk!");
5c4054a50dbb 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 5343
diff changeset
   822
  }
5c4054a50dbb 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 5343
diff changeset
   823
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
const char* ConcurrentMarkSweepGeneration::name() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
  return "concurrent mark-sweep generation";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
void ConcurrentMarkSweepGeneration::update_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
    _space_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
// this is an optimized version of update_counters(). it takes the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
// used value as a parameter rather than computing it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
void ConcurrentMarkSweepGeneration::update_counters(size_t used) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
    _space_counters->update_used(used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
    _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
void ConcurrentMarkSweepGeneration::print() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
  Generation::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
  cmsSpace()->print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
void ConcurrentMarkSweepGeneration::print_statistics() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
  cmsSpace()->printFLCensus(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
void ConcurrentMarkSweepGeneration::printOccupancy(const char *s) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
  if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
    if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
      gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
        level(), short_name(), s, used(), capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
      gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
        level(), short_name(), s, used() / K, capacity() / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
  if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
    gclog_or_tty->print(" "SIZE_FORMAT"("SIZE_FORMAT")",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
              gch->used(), gch->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
    gclog_or_tty->print(" "SIZE_FORMAT"K("SIZE_FORMAT"K)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
              gch->used() / K, gch->capacity() / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
size_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
ConcurrentMarkSweepGeneration::contiguous_available() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
  // dld proposes an improvement in precision here. If the committed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
  // part of the space ends in a free block we should add that to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
  // uncommitted size in the calculation below. Will make this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
  // change later, staying with the approximation below for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
  // time being. -- ysr.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
  return MAX2(_virtual_space.uncommitted_size(), unsafe_max_alloc_nogc());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
size_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
ConcurrentMarkSweepGeneration::unsafe_max_alloc_nogc() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
  return _cmsSpace->max_alloc_in_words() * HeapWordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
size_t ConcurrentMarkSweepGeneration::max_available() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
  return free() + _virtual_space.uncommitted_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
6985
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
   897
bool ConcurrentMarkSweepGeneration::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const {
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
   898
  size_t available = max_available();
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
   899
  size_t av_promo  = (size_t)gc_stats()->avg_promoted()->padded_average();
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
   900
  bool   res = (available >= av_promo) || (available >= max_promotion_in_bytes);
7419
263dd4e89b9d 7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
ysr
parents: 7397
diff changeset
   901
  if (Verbose && PrintGCDetails) {
6985
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
   902
    gclog_or_tty->print_cr(
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
   903
      "CMS: promo attempt is%s safe: available("SIZE_FORMAT") %s av_promo("SIZE_FORMAT"),"
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
   904
      "max_promo("SIZE_FORMAT")",
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
   905
      res? "":" not", available, res? ">=":"<",
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
   906
      av_promo, max_promotion_in_bytes);
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
   907
  }
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
   908
  return res;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   911
// At a promotion failure dump information on block layout in heap
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   912
// (cms old generation).
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   913
void ConcurrentMarkSweepGeneration::promotion_failure_occurred() {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   914
  if (CMSDumpAtPromotionFailure) {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   915
    cmsSpace()->dump_at_safepoint_with_locks(collector(), gclog_or_tty);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   916
  }
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   917
}
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   918
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
CompactibleSpace*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
ConcurrentMarkSweepGeneration::first_compaction_space() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
  return _cmsSpace;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
void ConcurrentMarkSweepGeneration::reset_after_compaction() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
  // Clear the promotion information.  These pointers can be adjusted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
  // along with all the other pointers into the heap but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
  // compaction is expected to be a rare event with
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
  // a heap using cms so don't do it without seeing the need.
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
   929
  if (CollectedHeap::use_parallel_gc_threads()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
    for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
      _par_gc_thread_states[i]->promo.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
void ConcurrentMarkSweepGeneration::space_iterate(SpaceClosure* blk, bool usedOnly) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
  blk->do_space(_cmsSpace);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
void ConcurrentMarkSweepGeneration::compute_new_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
  // If incremental collection failed, we just want to expand
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
  // to the limit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
  if (incremental_collection_failed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
    clear_incremental_collection_failed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
    grow_to_reserved();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
  size_t expand_bytes = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
  double free_percentage = ((double) free()) / capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
  double desired_free_percentage = (double) MinHeapFreeRatio / 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
  double maximum_free_percentage = (double) MaxHeapFreeRatio / 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
  // compute expansion delta needed for reaching desired free percentage
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
  if (free_percentage < desired_free_percentage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
    size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
    assert(desired_capacity >= capacity(), "invalid expansion size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
    expand_bytes = MAX2(desired_capacity - capacity(), MinHeapDeltaBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
  if (expand_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
      size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
      gclog_or_tty->print_cr("\nFrom compute_new_size: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
      gclog_or_tty->print_cr("  Free fraction %f", free_percentage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
      gclog_or_tty->print_cr("  Desired free fraction %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
        desired_free_percentage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
      gclog_or_tty->print_cr("  Maximum free fraction %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
        maximum_free_percentage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
      gclog_or_tty->print_cr("  Capactiy "SIZE_FORMAT, capacity()/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
      gclog_or_tty->print_cr("  Desired capacity "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
        desired_capacity/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
      int prev_level = level() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
      if (prev_level >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
        size_t prev_size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
        GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
        Generation* prev_gen = gch->_gens[prev_level];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
        prev_size = prev_gen->capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
          gclog_or_tty->print_cr("  Younger gen size "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
                                 prev_size/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
      gclog_or_tty->print_cr("  unsafe_max_alloc_nogc "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
        unsafe_max_alloc_nogc()/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
      gclog_or_tty->print_cr("  contiguous available "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
        contiguous_available()/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
      gclog_or_tty->print_cr("  Expand by "SIZE_FORMAT" (bytes)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
        expand_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
    // safe if expansion fails
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
    expand(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
      gclog_or_tty->print_cr("  Expanded free fraction %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
        ((double) free()) / capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
Mutex* ConcurrentMarkSweepGeneration::freelistLock() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
  return cmsSpace()->freelistLock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
HeapWord* ConcurrentMarkSweepGeneration::allocate(size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
                                                  bool   tlab) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
  CMSSynchronousYieldRequest yr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
  MutexLockerEx x(freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
                  Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
  return have_lock_and_allocate(size, tlab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
HeapWord* ConcurrentMarkSweepGeneration::have_lock_and_allocate(size_t size,
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1012
                                                  bool   tlab /* ignored */) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
  size_t adjustedSize = CompactibleFreeListSpace::adjustObjectSize(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
  HeapWord* res = cmsSpace()->allocate(adjustedSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
  // Allocate the object live (grey) if the background collector has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
  // started marking. This is necessary because the marker may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
  // have passed this address and consequently this object will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
  // not otherwise be greyed and would be incorrectly swept up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
  // Note that if this object contains references, the writing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
  // of those references will dirty the card containing this object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
  // allowing the object to be blackened (and its references scanned)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
  // either during a preclean phase or at the final checkpoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
  if (res != NULL) {
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1025
    // We may block here with an uninitialized object with
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1026
    // its mark-bit or P-bits not yet set. Such objects need
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1027
    // to be safely navigable by block_start().
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1028
    assert(oop(res)->klass_or_null() == NULL, "Object should be uninitialized here.");
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1029
    assert(!((FreeChunk*)res)->isFree(), "Error, block will look free but show wrong size");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
    collector()->direct_allocated(res, adjustedSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
    _direct_allocated_words += adjustedSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
    // allocation counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
      _numObjectsAllocated++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
      _numWordsAllocated += (int)adjustedSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
// In the case of direct allocation by mutators in a generation that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
// is being concurrently collected, the object must be allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
// live (grey) if the background collector has started marking.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
// This is necessary because the marker may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
// have passed this address and consequently this object will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
// not otherwise be greyed and would be incorrectly swept up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
// Note that if this object contains references, the writing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
// of those references will dirty the card containing this object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
// allowing the object to be blackened (and its references scanned)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
// either during a preclean phase or at the final checkpoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
void CMSCollector::direct_allocated(HeapWord* start, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
  assert(_markBitMap.covers(start, size), "Out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
  if (_collectorState >= Marking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
    MutexLockerEx y(_markBitMap.lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
                    Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
    // [see comments preceding SweepClosure::do_blk() below for details]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
    // 1. need to mark the object as live so it isn't collected
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
    // 2. need to mark the 2nd bit to indicate the object may be uninitialized
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1059
    // 3. need to mark the end of the object so marking, precleaning or sweeping
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1060
    //    can skip over uninitialized or unparsable objects. An allocated
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1061
    //    object is considered uninitialized for our purposes as long as
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1062
    //    its klass word is NULL. (Unparsable objects are those which are
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1063
    //    initialized in the sense just described, but whose sizes can still
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1064
    //    not be correctly determined. Note that the class of unparsable objects
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1065
    //    can only occur in the perm gen. All old gen objects are parsable
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1066
    //    as soon as they are initialized.)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
    _markBitMap.mark(start);          // object is live
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
    _markBitMap.mark(start + 1);      // object is potentially uninitialized?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
    _markBitMap.mark(start + size - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
                                      // mark end of object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
  // check that oop looks uninitialized
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1073
  assert(oop(start)->klass_or_null() == NULL, "_klass should be NULL");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
void CMSCollector::promoted(bool par, HeapWord* start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
                            bool is_obj_array, size_t obj_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
  assert(_markBitMap.covers(start), "Out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
  // See comment in direct_allocated() about when objects should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
  // be allocated live.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
  if (_collectorState >= Marking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
    // we already hold the marking bit map lock, taken in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
    // the prologue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
    if (par) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
      _markBitMap.par_mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
      _markBitMap.mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
    // We don't need to mark the object as uninitialized (as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
    // in direct_allocated above) because this is being done with the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
    // world stopped and the object will be initialized by the
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1092
    // time the marking, precleaning or sweeping get to look at it.
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1093
    // But see the code for copying objects into the CMS generation,
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1094
    // where we need to ensure that concurrent readers of the
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1095
    // block offset table are able to safely navigate a block that
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1096
    // is in flux from being free to being allocated (and in
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1097
    // transition while being copied into) and subsequently
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1098
    // becoming a bona-fide object when the copy/promotion is complete.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
    assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
           "expect promotion only at safepoints");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
    if (_collectorState < Sweeping) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
      // Mark the appropriate cards in the modUnionTable, so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
      // this object gets scanned before the sweep. If this is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
      // not done, CMS generation references in the object might
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
      // not get marked.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
      // For the case of arrays, which are otherwise precisely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
      // marked, we need to dirty the entire array, not just its head.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
      if (is_obj_array) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
        // The [par_]mark_range() method expects mr.end() below to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
        // be aligned to the granularity of a bit's representation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
        // in the heap. In the case of the MUT below, that's a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
        // card size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
        MemRegion mr(start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
                     (HeapWord*)round_to((intptr_t)(start + obj_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
                        CardTableModRefBS::card_size /* bytes */));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
        if (par) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
          _modUnionTable.par_mark_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
          _modUnionTable.mark_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
      } else {  // not an obj array; we can just mark the head
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
        if (par) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
          _modUnionTable.par_mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
          _modUnionTable.mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
static inline size_t percent_of_space(Space* space, HeapWord* addr)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
  size_t delta = pointer_delta(addr, space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
  return (size_t)(delta * 100.0 / (space->capacity() / HeapWordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
void CMSCollector::icms_update_allocation_limits()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
  Generation* gen0 = GenCollectedHeap::heap()->get_gen(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
  EdenSpace* eden = gen0->as_DefNewGeneration()->eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
  const unsigned int duty_cycle = stats().icms_update_duty_cycle();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
  if (CMSTraceIncrementalPacing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
    stats().print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
  assert(duty_cycle <= 100, "invalid duty cycle");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
  if (duty_cycle != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
    // The duty_cycle is a percentage between 0 and 100; convert to words and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
    // then compute the offset from the endpoints of the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
    size_t free_words = eden->free() / HeapWordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
    double free_words_dbl = (double)free_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
    size_t duty_cycle_words = (size_t)(free_words_dbl * duty_cycle / 100.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
    size_t offset_words = (free_words - duty_cycle_words) / 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
    _icms_start_limit = eden->top() + offset_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
    _icms_stop_limit = eden->end() - offset_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
    // The limits may be adjusted (shifted to the right) by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
    // CMSIncrementalOffset, to allow the application more mutator time after a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
    // young gen gc (when all mutators were stopped) and before CMS starts and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
    // takes away one or more cpus.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
    if (CMSIncrementalOffset != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
      double adjustment_dbl = free_words_dbl * CMSIncrementalOffset / 100.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
      size_t adjustment = (size_t)adjustment_dbl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
      HeapWord* tmp_stop = _icms_stop_limit + adjustment;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
      if (tmp_stop > _icms_stop_limit && tmp_stop < eden->end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
        _icms_start_limit += adjustment;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
        _icms_stop_limit = tmp_stop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
  if (duty_cycle == 0 || (_icms_start_limit == _icms_stop_limit)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
    _icms_start_limit = _icms_stop_limit = eden->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
  // Install the new start limit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
  eden->set_soft_end(_icms_start_limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
  if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
    gclog_or_tty->print(" icms alloc limits:  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
                           PTR_FORMAT "," PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
                           " (" SIZE_FORMAT "%%," SIZE_FORMAT "%%) ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
                           _icms_start_limit, _icms_stop_limit,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
                           percent_of_space(eden, _icms_start_limit),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
                           percent_of_space(eden, _icms_stop_limit));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
    if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
      gclog_or_tty->print("eden:  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
      eden->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
// Any changes here should try to maintain the invariant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
// that if this method is called with _icms_start_limit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
// and _icms_stop_limit both NULL, then it should return NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
// and not notify the icms thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
CMSCollector::allocation_limit_reached(Space* space, HeapWord* top,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
                                       size_t word_size)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
  // A start_limit equal to end() means the duty cycle is 0, so treat that as a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
  // nop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
  if (CMSIncrementalMode && _icms_start_limit != space->end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
    if (top <= _icms_start_limit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
      if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
        space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
        gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
        gclog_or_tty->print_cr(" start limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
                               ", new limit=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
                               " (" SIZE_FORMAT "%%)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
                               top, _icms_stop_limit,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
                               percent_of_space(space, _icms_stop_limit));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
      ConcurrentMarkSweepThread::start_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
      assert(top < _icms_stop_limit, "Tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
      if (word_size < pointer_delta(_icms_stop_limit, top)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
        return _icms_stop_limit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
      // The allocation will cross both the _start and _stop limits, so do the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
      // stop notification also and return end().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
      if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
        space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
        gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
        gclog_or_tty->print_cr(" +stop limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
                               ", new limit=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
                               " (" SIZE_FORMAT "%%)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
                               top, space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
                               percent_of_space(space, space->end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
      ConcurrentMarkSweepThread::stop_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
      return space->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
    if (top <= _icms_stop_limit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
      if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
        space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1241
        gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
        gclog_or_tty->print_cr(" stop limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
                               ", new limit=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
                               " (" SIZE_FORMAT "%%)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
                               top, space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
                               percent_of_space(space, space->end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
      ConcurrentMarkSweepThread::stop_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
      return space->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
    if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
      space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
      gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
      gclog_or_tty->print_cr(" end limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
                             ", new limit=" PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
                             top, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  1264
oop ConcurrentMarkSweepGeneration::promote(oop obj, size_t obj_size) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
  assert(obj_size == (size_t)obj->size(), "bad obj_size passed in");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
  // allocate, copy and if necessary update promoinfo --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
  // delegate to underlying space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
  if (Universe::heap()->promotion_should_fail()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
#endif  // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  1276
  oop res = _cmsSpace->promote(obj, obj_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
  if (res == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
    // expand and retry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
    size_t s = _cmsSpace->expansionSpaceRequired(obj_size);  // HeapWords
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
    expand(s*HeapWordSize, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
      CMSExpansionCause::_satisfy_promotion);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
    // Since there's currently no next generation, we don't try to promote
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
    // into a more senior generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
    assert(next_gen() == NULL, "assumption, based upon which no attempt "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
                               "is made to pass on a possibly failing "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
                               "promotion to next generation");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  1287
    res = _cmsSpace->promote(obj, obj_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
  if (res != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
    // See comment in allocate() about when objects should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
    // be allocated live.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
    assert(obj->is_oop(), "Will dereference klass pointer below");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
    collector()->promoted(false,           // Not parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
                          (HeapWord*)res, obj->is_objArray(), obj_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
    // promotion counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
      _numObjectsPromoted++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
      _numWordsPromoted +=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
        (int)(CompactibleFreeListSpace::adjustObjectSize(obj->size()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
ConcurrentMarkSweepGeneration::allocation_limit_reached(Space* space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
                                             HeapWord* top,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
                                             size_t word_sz)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
  return collector()->allocation_limit_reached(space, top, word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1314
// IMPORTANT: Notes on object size recognition in CMS.
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1315
// ---------------------------------------------------
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1316
// A block of storage in the CMS generation is always in
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1317
// one of three states. A free block (FREE), an allocated
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1318
// object (OBJECT) whose size() method reports the correct size,
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1319
// and an intermediate state (TRANSIENT) in which its size cannot
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1320
// be accurately determined.
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1321
// STATE IDENTIFICATION:   (32 bit and 64 bit w/o COOPS)
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1322
// -----------------------------------------------------
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1323
// FREE:      klass_word & 1 == 1; mark_word holds block size
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1324
//
6447
32cc5cad7fa6 6983930: CMS: Various small cleanups ca September 2010
ysr
parents: 6262
diff changeset
  1325
// OBJECT:    klass_word installed; klass_word != 0 && klass_word & 1 == 0;
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1326
//            obj->size() computes correct size
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1327
//            [Perm Gen objects needs to be "parsable" before they can be navigated]
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1328
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1329
// TRANSIENT: klass_word == 0; size is indeterminate until we become an OBJECT
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1330
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1331
// STATE IDENTIFICATION: (64 bit+COOPS)
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1332
// ------------------------------------
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1333
// FREE:      mark_word & CMS_FREE_BIT == 1; mark_word & ~CMS_FREE_BIT gives block_size
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1334
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1335
// OBJECT:    klass_word installed; klass_word != 0;
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1336
//            obj->size() computes correct size
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1337
//            [Perm Gen comment above continues to hold]
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1338
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1339
// TRANSIENT: klass_word == 0; size is indeterminate until we become an OBJECT
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1340
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1341
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1342
// STATE TRANSITION DIAGRAM
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1343
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1344
//        mut / parnew                     mut  /  parnew
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1345
// FREE --------------------> TRANSIENT ---------------------> OBJECT --|
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1346
//  ^                                                                   |
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1347
//  |------------------------ DEAD <------------------------------------|
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1348
//         sweep                            mut
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1349
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1350
// While a block is in TRANSIENT state its size cannot be determined
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1351
// so readers will either need to come back later or stall until
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1352
// the size can be determined. Note that for the case of direct
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1353
// allocation, P-bits, when available, may be used to determine the
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1354
// size of an object that may not yet have been initialized.
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1355
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
// Things to support parallel young-gen collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
ConcurrentMarkSweepGeneration::par_promote(int thread_num,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
                                           oop old, markOop m,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1360
                                           size_t word_sz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1361
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1362
  if (Universe::heap()->promotion_should_fail()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
#endif  // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
  CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
  PromotionInfo* promoInfo = &ps->promo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
  // if we are tracking promotions, then first ensure space for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
  // promotion (including spooling space for saving header if necessary).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
  // then allocate and copy, then track promoted info if needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
  // When tracking (see PromotionInfo::track()), the mark word may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
  // be displaced and in this case restoration of the mark word
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
  // occurs in the (oop_since_save_marks_)iterate phase.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
  if (promoInfo->tracking() && !promoInfo->ensure_spooling_space()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
    // Out of space for allocating spooling buffers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
    // try expanding and allocating spooling buffers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
    if (!expand_and_ensure_spooling_space(promoInfo)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
  assert(promoInfo->has_spooling_space(), "Control point invariant");
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1383
  const size_t alloc_sz = CompactibleFreeListSpace::adjustObjectSize(word_sz);
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1384
  HeapWord* obj_ptr = ps->lab.alloc(alloc_sz);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
  if (obj_ptr == NULL) {
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1386
     obj_ptr = expand_and_par_lab_allocate(ps, alloc_sz);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
     if (obj_ptr == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
       return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
  oop obj = oop(obj_ptr);
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1392
  OrderAccess::storestore();
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1393
  assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1394
  assert(!((FreeChunk*)obj_ptr)->isFree(), "Error, block will look free but show wrong size");
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1395
  // IMPORTANT: See note on object initialization for CMS above.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
  // Otherwise, copy the object.  Here we must be careful to insert the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
  // klass pointer last, since this marks the block as an allocated object.
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1398
  // Except with compressed oops it's the mark word.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
  HeapWord* old_ptr = (HeapWord*)old;
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1400
  // Restore the mark word copied above.
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1401
  obj->set_mark(m);
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1402
  assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1403
  assert(!((FreeChunk*)obj_ptr)->isFree(), "Error, block will look free but show wrong size");
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1404
  OrderAccess::storestore();
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1405
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1406
  if (UseCompressedOops) {
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1407
    // Copy gap missed by (aligned) header size calculation below
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1408
    obj->set_klass_gap(old->klass_gap());
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1409
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
  if (word_sz > (size_t)oopDesc::header_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
    Copy::aligned_disjoint_words(old_ptr + oopDesc::header_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
                                 obj_ptr + oopDesc::header_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
                                 word_sz - oopDesc::header_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
  }
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1415
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
  // Now we can track the promoted object, if necessary.  We take care
5434
a2e785749780 6951188: CMS: move PromotionInfo into its own file
ysr
parents: 5433
diff changeset
  1417
  // to delay the transition from uninitialized to full object
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
  // (i.e., insertion of klass pointer) until after, so that it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
  // atomically becomes a promoted object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
  if (promoInfo->tracking()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
    promoInfo->track((PromotedObject*)obj, old->klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
  }
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1423
  assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1424
  assert(!((FreeChunk*)obj_ptr)->isFree(), "Error, block will look free but show wrong size");
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1425
  assert(old->is_oop(), "Will use and dereference old klass ptr below");
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1426
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1427
  // Finally, install the klass pointer (this should be volatile).
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1428
  OrderAccess::storestore();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
  obj->set_klass(old->klass());
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1430
  // We should now be able to calculate the right size for this object
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1431
  assert(obj->is_oop() && obj->size() == (int)word_sz, "Error, incorrect size computed for promoted object");
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1432
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
  collector()->promoted(true,          // parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
                        obj_ptr, old->is_objArray(), word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
  NOT_PRODUCT(
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1437
    Atomic::inc_ptr(&_numObjectsPromoted);
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1438
    Atomic::add_ptr(alloc_sz, &_numWordsPromoted);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
  return obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
ConcurrentMarkSweepGeneration::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
par_promote_alloc_undo(int thread_num,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
                       HeapWord* obj, size_t word_sz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
  // CMS does not support promotion undo.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
  ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
ConcurrentMarkSweepGeneration::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
par_promote_alloc_done(int thread_num) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
  CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  1456
  ps->lab.retire(thread_num);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
ConcurrentMarkSweepGeneration::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
par_oop_since_save_marks_iterate_done(int thread_num) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
  CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
  ParScanWithoutBarrierClosure* dummy_cl = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
  ps->promo.promoted_oops_iterate_nv(dummy_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
// XXXPERM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
bool ConcurrentMarkSweepGeneration::should_collect(bool   full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
                                                   size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
                                                   bool   tlab)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
  // We allow a STW collection only if a full
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
  // collection was requested.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
  return full || should_allocate(size, tlab); // FIX ME !!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
  // This and promotion failure handling are connected at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
  // hip and should be fixed by untying them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
bool CMSCollector::shouldConcurrentCollect() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
  if (_full_gc_requested) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
      gclog_or_tty->print_cr("CMSCollector: collect because of explicit "
5433
c182d4c3039e 6919638: CMS: ExplicitGCInvokesConcurrent misinteracts with gc locker
ysr
parents: 5431
diff changeset
  1483
                             " gc request (or gc_locker)");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
  // For debugging purposes, change the type of collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
  // If the rotation is not on the concurrent collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
  // type, don't start a concurrent collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
    if (RotateCMSCollectionTypes &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
        (_cmsGen->debug_collection_type() !=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
          ConcurrentMarkSweepGeneration::Concurrent_collection_type)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
      assert(_cmsGen->debug_collection_type() !=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
        ConcurrentMarkSweepGeneration::Unknown_collection_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
        "Bad cms collection type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1499
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1501
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
  FreelistLocker x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
  // ------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
  // Print out lots of information which affects the initiation of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
  // a collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
  if (PrintCMSInitiationStatistics && stats().valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
    gclog_or_tty->print("CMSCollector shouldConcurrentCollect: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
    gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
    gclog_or_tty->print_cr("");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
    stats().print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
    gclog_or_tty->print_cr("time_until_cms_gen_full %3.7f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
      stats().time_until_cms_gen_full());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
    gclog_or_tty->print_cr("free="SIZE_FORMAT, _cmsGen->free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1514
    gclog_or_tty->print_cr("contiguous_available="SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1515
                           _cmsGen->contiguous_available());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
    gclog_or_tty->print_cr("promotion_rate=%g", stats().promotion_rate());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
    gclog_or_tty->print_cr("cms_allocation_rate=%g", stats().cms_allocation_rate());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1518
    gclog_or_tty->print_cr("occupancy=%3.7f", _cmsGen->occupancy());
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1519
    gclog_or_tty->print_cr("initiatingOccupancy=%3.7f", _cmsGen->initiating_occupancy());
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1520
    gclog_or_tty->print_cr("initiatingPermOccupancy=%3.7f", _permGen->initiating_occupancy());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1521
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1522
  // ------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1523
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1524
  // If the estimated time to complete a cms collection (cms_duration())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1525
  // is less than the estimated time remaining until the cms generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
  // is full, start a collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
  if (!UseCMSInitiatingOccupancyOnly) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
    if (stats().valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
      if (stats().time_until_cms_start() == 0.0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1530
        return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
      // We want to conservatively collect somewhat early in order
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
      // to try and "bootstrap" our CMS/promotion statistics;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
      // this branch will not fire after the first successful CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
      // collection because the stats should then be valid.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
      if (_cmsGen->occupancy() >= _bootstrap_occupancy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
        if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
          gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1540
            " CMSCollector: collect for bootstrapping statistics:"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
            " occupancy = %f, boot occupancy = %f", _cmsGen->occupancy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
            _bootstrap_occupancy);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
        return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
  // Otherwise, we start a collection cycle if either the perm gen or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
  // old gen want a collection cycle started. Each may use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
  // an appropriate criterion for making this decision.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
  // XXX We need to make sure that the gen expansion
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1553
  // criterion dovetails well with this. XXX NEED TO FIX THIS
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1554
  if (_cmsGen->should_concurrent_collect()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
      gclog_or_tty->print_cr("CMS old gen initiated");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1561
  // We start a collection if we believe an incremental collection may fail;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1562
  // this is not likely to be productive in practice because it's probably too
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1563
  // late anyway.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1564
  GenCollectedHeap* gch = GenCollectedHeap::heap();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1565
  assert(gch->collector_policy()->is_two_generation_policy(),
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1566
         "You may want to check the correctness of the following");
7419
263dd4e89b9d 7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
ysr
parents: 7397
diff changeset
  1567
  if (gch->incremental_collection_will_fail(true /* consult_young */)) {
263dd4e89b9d 7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
ysr
parents: 7397
diff changeset
  1568
    if (Verbose && PrintGCDetails) {
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1569
      gclog_or_tty->print("CMSCollector: collect because incremental collection will fail ");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1574
  if (CMSClassUnloadingEnabled && _permGen->should_concurrent_collect()) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1575
    bool res = update_should_unload_classes();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1576
    if (res) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1577
      if (Verbose && PrintGCDetails) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1578
        gclog_or_tty->print_cr("CMS perm gen initiated");
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1579
      }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1580
      return true;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1581
    }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1582
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1584
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1585
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1586
// Clear _expansion_cause fields of constituent generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1587
void CMSCollector::clear_expansion_cause() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1588
  _cmsGen->clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1589
  _permGen->clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1590
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1591
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1592
// We should be conservative in starting a collection cycle.  To
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1593
// start too eagerly runs the risk of collecting too often in the
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1594
// extreme.  To collect too rarely falls back on full collections,
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1595
// which works, even if not optimum in terms of concurrent work.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1596
// As a work around for too eagerly collecting, use the flag
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1597
// UseCMSInitiatingOccupancyOnly.  This also has the advantage of
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1598
// giving the user an easily understandable way of controlling the
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1599
// collections.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1600
// We want to start a new collection cycle if any of the following
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1601
// conditions hold:
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1602
// . our current occupancy exceeds the configured initiating occupancy
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1603
//   for this generation, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1604
// . we recently needed to expand this space and have not, since that
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1605
//   expansion, done a collection of this generation, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1606
// . the underlying space believes that it may be a good idea to initiate
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1607
//   a concurrent collection (this may be based on criteria such as the
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1608
//   following: the space uses linear allocation and linear allocation is
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1609
//   going to fail, or there is believed to be excessive fragmentation in
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1610
//   the generation, etc... or ...
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1611
// [.(currently done by CMSCollector::shouldConcurrentCollect() only for
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1612
//   the case of the old generation, not the perm generation; see CR 6543076):
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1613
//   we may be approaching a point at which allocation requests may fail because
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1614
//   we will be out of sufficient free space given allocation rate estimates.]
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1615
bool ConcurrentMarkSweepGeneration::should_concurrent_collect() const {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1616
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
  assert_lock_strong(freelistLock());
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1618
  if (occupancy() > initiating_occupancy()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1620
      gclog_or_tty->print(" %s: collect because of occupancy %f / %f  ",
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1621
        short_name(), occupancy(), initiating_occupancy());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1622
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1624
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1625
  if (UseCMSInitiatingOccupancyOnly) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1626
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
  if (expansion_cause() == CMSExpansionCause::_satisfy_allocation) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
      gclog_or_tty->print(" %s: collect because expanded for allocation ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
        short_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
  }
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1635
  if (_cmsSpace->should_concurrent_collect()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
    if (PrintGCDetails && Verbose) {
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1637
      gclog_or_tty->print(" %s: collect because cmsSpace says so ",
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1638
        short_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1644
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1645
void ConcurrentMarkSweepGeneration::collect(bool   full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
                                            bool   clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1647
                                            size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
                                            bool   tlab)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1650
  collector()->collect(full, clear_all_soft_refs, size, tlab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1651
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1652
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1653
void CMSCollector::collect(bool   full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1654
                           bool   clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1655
                           size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1656
                           bool   tlab)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1658
  if (!UseCMSCollectionPassing && _collectorState > Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
    // For debugging purposes skip the collection if the state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
    // is not currently idle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1661
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
      gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " skipped full:%d CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
        Thread::current(), full, _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
  // The following "if" branch is present for defensive reasons.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1669
  // In the current uses of this interface, it can be replaced with:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
  // assert(!GC_locker.is_active(), "Can't be called otherwise");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
  // But I am not placing that assert here to allow future
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
  // generality in invoking this interface.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
  if (GC_locker::is_active()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
    // A consistency test for GC_locker
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
    assert(GC_locker::needs_gc(), "Should have been set already");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
    // Skip this foreground collection, instead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
    // expanding the heap if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
    // Need the free list locks for the call to free() in compute_new_size()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
    compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
  acquire_control_and_collect(full, clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
  _full_gcs_since_conc_gc++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
void CMSCollector::request_full_gc(unsigned int full_gc_count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
  unsigned int gc_count = gch->total_full_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
  if (gc_count == full_gc_count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
    MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
    _full_gc_requested = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
    CGC_lock->notify();   // nudge CMS thread
8684
7ebbd0b3e295 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 8296
diff changeset
  1694
  } else {
7ebbd0b3e295 6987703: iCMS: Intermittent hang with gc/gctests/CallGC/CallGC01 and +ExplicitGCInvokesConcurrent
ysr
parents: 8296
diff changeset
  1695
    assert(gc_count > full_gc_count, "Error: causal loop");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
// The foreground and background collectors need to coordinate in order
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
// to make sure that they do not mutually interfere with CMS collections.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
// When a background collection is active,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
// the foreground collector may need to take over (preempt) and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
// synchronously complete an ongoing collection. Depending on the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
// frequency of the background collections and the heap usage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
// of the application, this preemption can be seldom or frequent.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
// There are only certain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
// points in the background collection that the "collection-baton"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
// can be passed to the foreground collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
// The foreground collector will wait for the baton before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
// starting any part of the collection.  The foreground collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
// will only wait at one location.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1714
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
// The background collector will yield the baton before starting a new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
// phase of the collection (e.g., before initial marking, marking from roots,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1717
// precleaning, final re-mark, sweep etc.)  This is normally done at the head
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
// of the loop which switches the phases. The background collector does some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
// of the phases (initial mark, final re-mark) with the world stopped.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
// Because of locking involved in stopping the world,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
// the foreground collector should not block waiting for the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
// collector when it is doing a stop-the-world phase.  The background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
// collector will yield the baton at an additional point just before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
// it enters a stop-the-world phase.  Once the world is stopped, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
// background collector checks the phase of the collection.  If the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
// phase has not changed, it proceeds with the collection.  If the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
// phase has changed, it skips that phase of the collection.  See
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
// the comments on the use of the Heap_lock in collect_in_background().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
// Variable used in baton passing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
//   _foregroundGCIsActive - Set to true by the foreground collector when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
//      it wants the baton.  The foreground clears it when it has finished
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
//      the collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
//   _foregroundGCShouldWait - Set to true by the background collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
//        when it is running.  The foreground collector waits while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
//      _foregroundGCShouldWait is true.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
//  CGC_lock - monitor used to protect access to the above variables
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
//      and to notify the foreground and background collectors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
//  _collectorState - current state of the CMS collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
// The foreground collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
//   acquires the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
//   sets _foregroundGCIsActive
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
//   waits on the CGC_lock for _foregroundGCShouldWait to be false
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
//     various locks acquired in preparation for the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
//     are released so as not to block the background collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
//     that is in the midst of a collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
//   proceeds with the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
//   clears _foregroundGCIsActive
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
//   returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
// The background collector in a loop iterating on the phases of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
//      collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
//   acquires the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
//   sets _foregroundGCShouldWait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
//   if _foregroundGCIsActive is set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
//     clears _foregroundGCShouldWait, notifies _CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
//     waits on _CGC_lock for _foregroundGCIsActive to become false
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
//     and exits the loop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
//   otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
//     proceed with that phase of the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
//     if the phase is a stop-the-world phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
//       yield the baton once more just before enqueueing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
//       the stop-world CMS operation (executed by the VM thread).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
//   returns after all phases of the collection are done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
void CMSCollector::acquire_control_and_collect(bool full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
        bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
  assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
  assert(!Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
         "shouldn't try to acquire control from self!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1774
  // Start the protocol for acquiring control of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1775
  // collection from the background collector (aka CMS thread).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1776
  assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
         "VM thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
  // Remember the possibly interrupted state of an ongoing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1779
  // concurrent collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1780
  CollectorState first_state = _collectorState;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
  // Signal to a possibly ongoing concurrent collection that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1783
  // we want to do a foreground collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1784
  _foregroundGCIsActive = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1785
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
  // Disable incremental mode during a foreground collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1787
  ICMSDisabler icms_disabler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1788
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1789
  // release locks and wait for a notify from the background collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1790
  // releasing the locks in only necessary for phases which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
  // do yields to improve the granularity of the collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
  // We need to lock the Free list lock for the space that we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
  // currently collecting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
  assert(haveFreelistLocks(), "Must be holding free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
  bitMapLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
  releaseFreelistLocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1799
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
    if (_foregroundGCShouldWait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
      // We are going to be waiting for action for the CMS thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
      // it had better not be gone (for instance at shutdown)!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
      assert(ConcurrentMarkSweepThread::cmst() != NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1804
             "CMS thread must be running");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1805
      // Wait here until the background collector gives us the go-ahead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1806
      ConcurrentMarkSweepThread::clear_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
        ConcurrentMarkSweepThread::CMS_vm_has_token);  // release token
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
      // Get a possibly blocked CMS thread going:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
      //   Note that we set _foregroundGCIsActive true above,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
      //   without protection of the CGC_lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
      CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
      assert(!ConcurrentMarkSweepThread::vm_thread_wants_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
             "Possible deadlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
      while (_foregroundGCShouldWait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
        // wait for notification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
        CGC_lock->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
        // Possibility of delay/starvation here, since CMS token does
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
        // not know to give priority to VM thread? Actually, i think
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1819
        // there wouldn't be any delay/starvation, but the proof of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1820
        // that "fact" (?) appears non-trivial. XXX 20011219YSR
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1821
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
      ConcurrentMarkSweepThread::set_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
        ConcurrentMarkSweepThread::CMS_vm_has_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1825
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
  // The CMS_token is already held.  Get back the other locks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
  assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1828
         "VM thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
  getFreelistLocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
  bitMapLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1831
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1832
    gclog_or_tty->print_cr("CMS foreground collector has asked for control "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1833
      INTPTR_FORMAT " with first state %d", Thread::current(), first_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1834
    gclog_or_tty->print_cr("    gets control with state %d", _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1835
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1836
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1837
  // Check if we need to do a compaction, or if not, whether
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
  // we need to start the mark-sweep from scratch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
  bool should_compact    = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
  bool should_start_over = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
  decide_foreground_collection_type(clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
    &should_compact, &should_start_over);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
  if (RotateCMSCollectionTypes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
    if (_cmsGen->debug_collection_type() ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
        ConcurrentMarkSweepGeneration::MSC_foreground_collection_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1848
      should_compact = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
    } else if (_cmsGen->debug_collection_type() ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1850
               ConcurrentMarkSweepGeneration::MS_foreground_collection_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1851
      should_compact = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1854
)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1855
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1856
  if (PrintGCDetails && first_state > Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1857
    GCCause::Cause cause = GenCollectedHeap::heap()->gc_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1858
    if (GCCause::is_user_requested_gc(cause) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1859
        GCCause::is_serviceability_requested_gc(cause)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1860
      gclog_or_tty->print(" (concurrent mode interrupted)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1861
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1862
      gclog_or_tty->print(" (concurrent mode failure)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1863
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1864
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1865
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1866
  if (should_compact) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1867
    // If the collection is being acquired from the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
    // collector, there may be references on the discovered
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
    // references lists that have NULL referents (being those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
    // that were concurrently cleared by a mutator) or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
    // that are no longer active (having been enqueued concurrently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1872
    // by the mutator).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
    // Scrub the list of those references because Mark-Sweep-Compact
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
    // code assumes referents are not NULL and that all discovered
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1875
    // Reference objects are active.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1876
    ref_processor()->clean_up_discovered_references();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1877
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1878
    do_compaction_work(clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1879
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1880
    // Has the GC time limit been exceeded?
5343
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1881
    DefNewGeneration* young_gen = _young_gen->as_DefNewGeneration();
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1882
    size_t max_eden_size = young_gen->max_capacity() -
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1883
                           young_gen->to()->capacity() -
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1884
                           young_gen->from()->capacity();
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1885
    GenCollectedHeap* gch = GenCollectedHeap::heap();
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1886
    GCCause::Cause gc_cause = gch->gc_cause();
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1887
    size_policy()->check_gc_overhead_limit(_young_gen->used(),
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1888
                                           young_gen->eden()->used(),
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1889
                                           _cmsGen->max_capacity(),
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1890
                                           max_eden_size,
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1891
                                           full,
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1892
                                           gc_cause,
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1893
                                           gch->collector_policy());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1894
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1895
    do_mark_sweep_work(clear_all_soft_refs, first_state,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1896
      should_start_over);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1897
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1898
  // Reset the expansion cause, now that we just completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1899
  // a collection cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1900
  clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1901
  _foregroundGCIsActive = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
// Resize the perm generation and the tenured generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
// after obtaining the free list locks for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
// two generations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
void CMSCollector::compute_new_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
  FreelistLocker z(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
  _permGen->compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
  _cmsGen->compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
// A work method used by foreground collection to determine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
// what type of collection (compacting or not, continuing or fresh)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
// it should do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
// NOTE: the intent is to make UseCMSCompactAtFullCollection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
// and CMSCompactWhenClearAllSoftRefs the default in the future
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
// and do away with the flags after a suitable period.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
void CMSCollector::decide_foreground_collection_type(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
  bool clear_all_soft_refs, bool* should_compact,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
  bool* should_start_over) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
  // Normally, we'll compact only if the UseCMSCompactAtFullCollection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
  // flag is set, and we have either requested a System.gc() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
  // the number of full gc's since the last concurrent cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
  // has exceeded the threshold set by CMSFullGCsBeforeCompaction,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
  // or if an incremental collection has failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
  assert(gch->collector_policy()->is_two_generation_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
         "You may want to check the correctness of the following");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
  // Inform cms gen if this was due to partial collection failing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
  // The CMS gen may use this fact to determine its expansion policy.
7419
263dd4e89b9d 7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
ysr
parents: 7397
diff changeset
  1934
  if (gch->incremental_collection_will_fail(false /* don't consult_young */)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
    assert(!_cmsGen->incremental_collection_failed(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
           "Should have been noticed, reacted to and cleared");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
    _cmsGen->set_incremental_collection_failed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
  *should_compact =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
    UseCMSCompactAtFullCollection &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
    ((_full_gcs_since_conc_gc >= CMSFullGCsBeforeCompaction) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
     GCCause::is_user_requested_gc(gch->gc_cause()) ||
7419
263dd4e89b9d 7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
ysr
parents: 7397
diff changeset
  1943
     gch->incremental_collection_will_fail(true /* consult_young */));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
  *should_start_over = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
  if (clear_all_soft_refs && !*should_compact) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
    // We are about to do a last ditch collection attempt
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
    // so it would normally make sense to do a compaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
    // to reclaim as much space as possible.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
    if (CMSCompactWhenClearAllSoftRefs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
      // Default: The rationale is that in this case either
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
      // we are past the final marking phase, in which case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
      // we'd have to start over, or so little has been done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
      // that there's little point in saving that work. Compaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
      // appears to be the sensible choice in either case.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
      *should_compact = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1957
      // We have been asked to clear all soft refs, but not to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1958
      // compact. Make sure that we aren't past the final checkpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1959
      // phase, for that is where we process soft refs. If we are already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
      // past that phase, we'll need to redo the refs discovery phase and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1961
      // if necessary clear soft refs that weren't previously
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1962
      // cleared. We do so by remembering the phase in which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1963
      // we came in, and if we are past the refs processing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1964
      // phase, we'll choose to just redo the mark-sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1965
      // collection from scratch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1966
      if (_collectorState > FinalMarking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
        // We are past the refs processing phase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1968
        // start over and do a fresh synchronous CMS cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1969
        _collectorState = Resetting; // skip to reset to start new cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
        reset(false /* == !asynch */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
        *should_start_over = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
      } // else we can continue a possibly ongoing current cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1973
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
// A work method used by the foreground collector to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1978
// a mark-sweep-compact.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1979
void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1981
  TraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1982
  if (PrintGC && Verbose && !(GCCause::is_user_requested_gc(gch->gc_cause()))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1983
    gclog_or_tty->print_cr("Compact ConcurrentMarkSweepGeneration after %d "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1984
      "collections passed to foreground collector", _full_gcs_since_conc_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1985
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1986
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1987
  // Sample collection interval time and reset for collection pause.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1988
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1989
    size_policy()->msc_collection_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1990
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1991
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1992
  // Temporarily widen the span of the weak reference processing to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1993
  // the entire heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1994
  MemRegion new_span(GenCollectedHeap::heap()->reserved_region());
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  1995
  ReferenceProcessorSpanMutator rp_mut_span(ref_processor(), new_span);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1996
  // Temporarily, clear the "is_alive_non_header" field of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1997
  // reference processor.
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  1998
  ReferenceProcessorIsAliveMutator rp_mut_closure(ref_processor(), NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1999
  // Temporarily make reference _processing_ single threaded (non-MT).
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  2000
  ReferenceProcessorMTProcMutator rp_mut_mt_processing(ref_processor(), false);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2001
  // Temporarily make refs discovery atomic
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  2002
  ReferenceProcessorAtomicMutator rp_mut_atomic(ref_processor(), true);
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  2003
  // Temporarily make reference _discovery_ single threaded (non-MT)
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  2004
  ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2005
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
  ref_processor()->set_enqueuing_is_done(false);
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10240
diff changeset
  2007
  ref_processor()->enable_discovery(false /*verify_disabled*/, false /*check_no_refs*/);
1610
5dddd195cc86 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 1606
diff changeset
  2008
  ref_processor()->setup_policy(clear_all_soft_refs);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
  // If an asynchronous collection finishes, the _modUnionTable is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
  // all clear.  If we are assuming the collection from an asynchronous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
  // collection, clear the _modUnionTable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
  assert(_collectorState != Idling || _modUnionTable.isAllClear(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
    "_modUnionTable should be clear if the baton was not passed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
  _modUnionTable.clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
  // We must adjust the allocation statistics being maintained
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
  // in the free list space. We do so by reading and clearing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
  // the sweep timer and updating the block flux rate estimates below.
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2019
  assert(!_intra_sweep_timer.is_active(), "_intra_sweep_timer should be inactive");
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2020
  if (_inter_sweep_timer.is_active()) {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2021
    _inter_sweep_timer.stop();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2022
    // Note that we do not use this sample to update the _inter_sweep_estimate.
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2023
    _cmsGen->cmsSpace()->beginSweepFLCensus((float)(_inter_sweep_timer.seconds()),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2024
                                            _inter_sweep_estimate.padded_average(),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2025
                                            _intra_sweep_estimate.padded_average());
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2026
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
  GenMarkSweep::invoke_at_safepoint(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2029
    ref_processor(), clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
  #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
    CompactibleFreeListSpace* cms_space = _cmsGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
    size_t free_size = cms_space->free();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
    assert(free_size ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2034
           pointer_delta(cms_space->end(), cms_space->compaction_top())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
           * HeapWordSize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
      "All the free space should be compacted into one chunk at top");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
    assert(cms_space->dictionary()->totalChunkSize(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2038
                                      debug_only(cms_space->freelistLock())) == 0 ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
           cms_space->totalSizeInIndexedFreeLists() == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2040
      "All the free space should be in a single chunk");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
    size_t num = cms_space->totalCount();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2042
    assert((free_size == 0 && num == 0) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2043
           (free_size > 0  && (num == 1 || num == 2)),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
         "There should be at most 2 free chunks after compaction");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
  #endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
  _collectorState = Resetting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2047
  assert(_restart_addr == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
         "Should have been NULL'd before baton was passed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
  reset(false /* == !asynch */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
  _cmsGen->reset_after_compaction();
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2051
  _concurrent_cycles_since_last_unload = 0;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2052
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2053
  if (verifying() && !should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2054
    perm_gen_verify_bit_map()->clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2055
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2056
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2057
  // Clear any data recorded in the PLAB chunk arrays.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2058
  if (_survivor_plab_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2059
    reset_survivor_plab_arrays();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2060
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2061
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2062
  // Adjust the per-size allocation stats for the next epoch.
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2063
  _cmsGen->cmsSpace()->endSweepFLCensus(sweep_count() /* fake */);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2064
  // Restart the "inter sweep timer" for the next epoch.
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2065
  _inter_sweep_timer.reset();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2066
  _inter_sweep_timer.start();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2067
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2068
  // Sample collection pause time and reset for collection interval.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2069
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2070
    size_policy()->msc_collection_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2071
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2072
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2073
  // For a mark-sweep-compact, compute_new_size() will be called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2074
  // in the heap's do_collection() method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2075
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2076
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2077
// A work method used by the foreground collector to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2078
// a mark-sweep, after taking over from a possibly on-going
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2079
// concurrent mark-sweep collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2080
void CMSCollector::do_mark_sweep_work(bool clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2081
  CollectorState first_state, bool should_start_over) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2082
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2083
    gclog_or_tty->print_cr("Pass concurrent collection to foreground "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2084
      "collector with count %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2085
      _full_gcs_since_conc_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2086
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2087
  switch (_collectorState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2088
    case Idling:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2089
      if (first_state == Idling || should_start_over) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2090
        // The background GC was not active, or should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2091
        // restarted from scratch;  start the cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2092
        _collectorState = InitialMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2093
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2094
      // If first_state was not Idling, then a background GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2095
      // was in progress and has now finished.  No need to do it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2096
      // again.  Leave the state as Idling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2097
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2098
    case Precleaning:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2099
      // In the foreground case don't do the precleaning since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2100
      // it is not done concurrently and there is extra work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2101
      // required.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2102
      _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2103
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2104
  if (PrintGCDetails &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
      (_collectorState > Idling ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2106
       !GCCause::is_user_requested_gc(GenCollectedHeap::heap()->gc_cause()))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2107
    gclog_or_tty->print(" (concurrent mode failure)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
  collect_in_foreground(clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
  // For a mark-sweep, compute_new_size() will be called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
  // in the heap's do_collection() method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2114
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
void CMSCollector::getFreelistLocks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
  // Get locks for all free lists in all generations that this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2118
  // collector is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
  _cmsGen->freelistLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
  _permGen->freelistLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
void CMSCollector::releaseFreelistLocks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
  // Release locks for all free lists in all generations that this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
  // collector is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
  _cmsGen->freelistLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
  _permGen->freelistLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
bool CMSCollector::haveFreelistLocks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
  // Check locks for all free lists in all generations that this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
  // collector is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2133
  assert_lock_strong(_cmsGen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2134
  assert_lock_strong(_permGen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
  PRODUCT_ONLY(ShouldNotReachHere());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2136
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2137
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2138
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2139
// A utility class that is used by the CMS collector to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2140
// temporarily "release" the foreground collector from its
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2141
// usual obligation to wait for the background collector to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2142
// complete an ongoing phase before proceeding.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2143
class ReleaseForegroundGC: public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2144
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2145
  CMSCollector* _c;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2146
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2147
  ReleaseForegroundGC(CMSCollector* c) : _c(c) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2148
    assert(_c->_foregroundGCShouldWait, "Else should not need to call");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2149
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2150
    // allow a potentially blocked foreground collector to proceed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2151
    _c->_foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2152
    if (_c->_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2153
      CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2154
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2155
    assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2156
           "Possible deadlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2157
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2158
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2159
  ~ReleaseForegroundGC() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2160
    assert(!_c->_foregroundGCShouldWait, "Usage protocol violation?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2161
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2162
    _c->_foregroundGCShouldWait = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2163
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2164
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2165
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2166
// There are separate collect_in_background and collect_in_foreground because of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2167
// the different locking requirements of the background collector and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2168
// foreground collector.  There was originally an attempt to share
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2169
// one "collect" method between the background collector and the foreground
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2170
// collector but the if-then-else required made it cleaner to have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2171
// separate methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2172
void CMSCollector::collect_in_background(bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
  assert(Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
    "A CMS asynchronous collection is only allowed on a CMS thread.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
    bool safepoint_check = Mutex::_no_safepoint_check_flag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2179
    MutexLockerEx hl(Heap_lock, safepoint_check);
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2180
    FreelistLocker fll(this);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2181
    MutexLockerEx x(CGC_lock, safepoint_check);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
    if (_foregroundGCIsActive || !UseAsyncConcMarkSweepGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
      // The foreground collector is active or we're
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
      // not using asynchronous collections.  Skip this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2185
      // background collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2186
      assert(!_foregroundGCShouldWait, "Should be clear");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2187
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2189
      assert(_collectorState == Idling, "Should be idling before start.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
      _collectorState = InitialMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
      // Reset the expansion cause, now that we are about to begin
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2192
      // a new cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
      clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
    }
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2195
    // Decide if we want to enable class unloading as part of the
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2196
    // ensuing concurrent GC cycle.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2197
    update_should_unload_classes();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2198
    _full_gc_requested = false;           // acks all outstanding full gc requests
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2199
    // Signal that we are about to start a collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2200
    gch->increment_total_full_collections();  // ... starting a collection cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2201
    _collection_count_start = gch->total_full_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2202
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2203
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
  // Used for PrintGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
  size_t prev_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2207
    prev_used = _cmsGen->used(); // XXXPERM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2208
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2209
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
  // The change of the collection state is normally done at this level;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2211
  // the exceptions are phases that are executed while the world is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
  // stopped.  For those phases the change of state is done while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
  // world is stopped.  For baton passing purposes this allows the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
  // background collector to finish the phase and change state atomically.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
  // The foreground collector cannot wait on a phase that is done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
  // while the world is stopped because the foreground collector already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
  // has the world stopped and would deadlock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
  while (_collectorState != Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
      gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " in CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
    // The foreground collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2224
    //   holds the Heap_lock throughout its collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2225
    //   holds the CMS token (but not the lock)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2226
    //     except while it is waiting for the background collector to yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2227
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2228
    // The foreground collector should be blocked (not for long)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2229
    //   if the background collector is about to start a phase
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2230
    //   executed with world stopped.  If the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2231
    //   collector has already started such a phase, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2232
    //   foreground collector is blocked waiting for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
    //   Heap_lock.  The stop-world phases (InitialMarking and FinalMarking)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
    //   are executed in the VM thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
    // The locking order is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
    //   PendingListLock (PLL)  -- if applicable (FinalMarking)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
    //   Heap_lock  (both this & PLL locked in VM_CMS_Operation::prologue())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
    //   CMS token  (claimed in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
    //                stop_world_and_do() -->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
    //                  safepoint_synchronize() -->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
    //                    CMSThread::synchronize())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
      // Check if the FG collector wants us to yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
      CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
      if (waitForForegroundGC()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
        // We yielded to a foreground GC, nothing more to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
        // done this round.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
        assert(_foregroundGCShouldWait == false, "We set it to false in "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
               "waitForForegroundGC()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
        if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
          gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2254
            " exiting collection CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
            Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2259
        // The background collector can run but check to see if the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2260
        // foreground collector has done a collection while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2261
        // background collector was waiting to get the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
        // above.  If yes, break so that _foregroundGCShouldWait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
        // is cleared before returning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
        if (_collectorState == Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
    assert(_foregroundGCShouldWait, "Foreground collector, if active, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
      "should be waiting");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2273
    switch (_collectorState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
      case InitialMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
          ReleaseForegroundGC x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
          stats().record_cms_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
          VM_CMS_Initial_Mark initial_mark_op(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
          VMThread::execute(&initial_mark_op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
        // The collector state may be any legal state at this point
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
        // since the background collector may have yielded to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
        // foreground collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2286
      case Marking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
        // initial marking in checkpointRootsInitialWork has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2288
        if (markFromRoots(true)) { // we were successful
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
          assert(_collectorState == Precleaning, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
            "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
          assert(_foregroundGCIsActive, "Internal state inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
      case Precleaning:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
          size_policy()->concurrent_precleaning_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
        // marking from roots in markFromRoots has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
        preclean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
          size_policy()->concurrent_precleaning_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
        assert(_collectorState == AbortablePreclean ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
               _collectorState == FinalMarking,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
               "Collector state should have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
      case AbortablePreclean:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
        size_policy()->concurrent_phases_resume();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
        abortable_preclean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2313
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2314
          size_policy()->concurrent_precleaning_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
        assert(_collectorState == FinalMarking, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2317
          "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2318
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
      case FinalMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2320
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
          ReleaseForegroundGC x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
          VM_CMS_Final_Remark final_remark_op(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2324
          VMThread::execute(&final_remark_op);
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  2325
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
        assert(_foregroundGCShouldWait, "block post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
      case Sweeping:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
          size_policy()->concurrent_sweeping_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
        // final marking in checkpointRootsFinal has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
        sweep(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
        assert(_collectorState == Resizing, "Collector state change "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2335
          "to Resizing must be done under the free_list_lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2336
        _full_gcs_since_conc_gc = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2337
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2338
        // Stop the timers for adaptive size policy for the concurrent phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2339
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2340
          size_policy()->concurrent_sweeping_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2341
          size_policy()->concurrent_phases_end(gch->gc_cause(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
                                             gch->prev_gen(_cmsGen)->capacity(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2343
                                             _cmsGen->free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
      case Resizing: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
        // Sweeping has been completed...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
        // At this point the background collection has completed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
        // Don't move the call to compute_new_size() down
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
        // into code that might be executed if the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
        // collection was preempted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
          ReleaseForegroundGC x(this);   // unblock FG collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
          MutexLockerEx       y(Heap_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
          CMSTokenSync        z(true);   // not strictly needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
          if (_collectorState == Resizing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
            compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
            _collectorState = Resetting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2360
            assert(_collectorState == Idling, "The state should only change"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2361
                   " because the foreground collector has finished the collection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2362
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2363
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2365
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2366
      case Resetting:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2367
        // CMS heap resizing has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2368
        reset(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2369
        assert(_collectorState == Idling, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2370
          "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2371
        stats().record_cms_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2372
        // Don't move the concurrent_phases_end() and compute_new_size()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2373
        // calls to here because a preempted background collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2374
        // has it's state set to "Resetting".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2375
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2376
      case Idling:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2377
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2378
        ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2379
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2381
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2382
      gclog_or_tty->print_cr("  Thread " INTPTR_FORMAT " done - next CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2383
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
    assert(_foregroundGCShouldWait, "block post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2386
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2387
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2388
  // Should this be in gc_epilogue?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
  collector_policy()->counters()->update_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2390
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
    // Clear _foregroundGCShouldWait and, in the event that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2393
    // foreground collector is waiting, notify it, before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
    // returning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2396
    _foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2397
    if (_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
      CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
    assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
           "Possible deadlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
      " exiting collection CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
      Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2409
    _cmsGen->print_heap_change(prev_used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2410
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2411
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2412
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
  assert(_foregroundGCIsActive && !_foregroundGCShouldWait,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
         "Foreground collector should be waiting, not executing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
  assert(Thread::current()->is_VM_thread(), "A foreground collection"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
    "may only be done by the VM Thread with the world stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
  assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
         "VM thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
  NOT_PRODUCT(TraceTime t("CMS:MS (foreground) ", PrintGCDetails && Verbose,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
    true, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
    size_policy()->ms_collection_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
  COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
  HandleMark hm;  // Discard invalid handles created during verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
  if (VerifyBeforeGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2431
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2432
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2433
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2434
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  2435
  // Snapshot the soft reference policy to be used in this collection cycle.
1610
5dddd195cc86 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 1606
diff changeset
  2436
  ref_processor()->setup_policy(clear_all_soft_refs);
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  2437
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2438
  bool init_mark_was_synchronous = false; // until proven otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2439
  while (_collectorState != Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2440
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2441
      gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " in CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2442
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2443
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2444
    switch (_collectorState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2445
      case InitialMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2446
        init_mark_was_synchronous = true;  // fact to be exploited in re-mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2447
        checkpointRootsInitial(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2448
        assert(_collectorState == Marking, "Collector state should have changed"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2449
          " within checkpointRootsInitial()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2450
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2451
      case Marking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2452
        // initial marking in checkpointRootsInitialWork has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2453
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2454
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2455
          gclog_or_tty->print("Verify before initial mark: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2456
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2457
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2458
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2459
          bool res = markFromRoots(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2460
          assert(res && _collectorState == FinalMarking, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2461
            "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2462
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2463
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2464
      case FinalMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2465
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2466
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2467
          gclog_or_tty->print("Verify before re-mark: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2468
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2469
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2470
        checkpointRootsFinal(false, clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2471
                             init_mark_was_synchronous);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2472
        assert(_collectorState == Sweeping, "Collector state should not "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2473
          "have changed within checkpointRootsFinal()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2474
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2475
      case Sweeping:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2476
        // final marking in checkpointRootsFinal has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2477
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2478
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2479
          gclog_or_tty->print("Verify before sweep: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2480
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2481
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2482
        sweep(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2483
        assert(_collectorState == Resizing, "Incorrect state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2484
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2485
      case Resizing: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2486
        // Sweeping has been completed; the actual resize in this case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2487
        // is done separately; nothing to be done in this state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2488
        _collectorState = Resetting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2489
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2490
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2491
      case Resetting:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2492
        // The heap has been resized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2493
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2494
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2495
          gclog_or_tty->print("Verify before reset: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2496
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2497
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2498
        reset(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2499
        assert(_collectorState == Idling, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2500
          "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2501
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2502
      case Precleaning:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2503
      case AbortablePreclean:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2504
        // Elide the preclean phase
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2505
        _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2506
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2507
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2508
        ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2509
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2510
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2511
      gclog_or_tty->print_cr("  Thread " INTPTR_FORMAT " done - next CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2513
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2514
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2515
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2516
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
    GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
    size_policy()->ms_collection_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2519
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2521
  if (VerifyAfterGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2524
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2525
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2526
    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
      " exiting collection CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2528
      Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2529
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2531
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
bool CMSCollector::waitForForegroundGC() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2533
  bool res = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2534
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2535
         "CMS thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2536
  // Block the foreground collector until the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2537
  // background collectors decides whether to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
  // yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
  MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2540
  _foregroundGCShouldWait = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
  if (_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
    // The background collector yields to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
    // foreground collector and returns a value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
    // indicating that it has yielded.  The foreground
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
    // collector can proceed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
    res = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
    _foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
    ConcurrentMarkSweepThread::clear_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
      ConcurrentMarkSweepThread::CMS_cms_has_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
    ConcurrentMarkSweepThread::set_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2551
      ConcurrentMarkSweepThread::CMS_cms_wants_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2552
    // Get a possibly blocked foreground thread going
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2553
    CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
      gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT " waiting at CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2556
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2557
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2558
    while (_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2559
      CGC_lock->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2560
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2561
    ConcurrentMarkSweepThread::set_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
      ConcurrentMarkSweepThread::CMS_cms_has_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
    ConcurrentMarkSweepThread::clear_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2564
      ConcurrentMarkSweepThread::CMS_cms_wants_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2565
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2566
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2567
    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT " continuing at CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2568
      Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2569
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2570
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2571
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2572
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2573
// Because of the need to lock the free lists and other structures in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2574
// the collector, common to all the generations that the collector is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
// collecting, we need the gc_prologues of individual CMS generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2576
// delegate to their collector. It may have been simpler had the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
// current infrastructure allowed one to call a prologue on a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
// collector. In the absence of that we have the generation's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2579
// prologue delegate to the collector, which delegates back
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2580
// some "local" work to a worker method in the individual generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
// that it's responsible for collecting, while itself doing any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
// work common to all generations it's responsible for. A similar
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
// comment applies to the  gc_epilogue()'s.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
// The role of the varaible _between_prologue_and_epilogue is to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
// enforce the invocation protocol.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
void CMSCollector::gc_prologue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
  // Call gc_prologue_work() for each CMSGen and PermGen that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
  // we are responsible for.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2590
  // The following locking discipline assumes that we are only called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2591
  // when the world is stopped.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2592
  assert(SafepointSynchronize::is_at_safepoint(), "world is stopped assumption");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2593
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2594
  // The CMSCollector prologue must call the gc_prologues for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
  // "generations" (including PermGen if any) that it's responsible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
  // for.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
  assert(   Thread::current()->is_VM_thread()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
         || (   CMSScavengeBeforeRemark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
             && Thread::current()->is_ConcurrentGC_thread()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
         "Incorrect thread type for prologue execution");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
  if (_between_prologue_and_epilogue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2604
    // We have already been invoked; this is a gc_prologue delegation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
    // from yet another CMS generation that we are responsible for, just
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
    // ignore it since all relevant work has already been done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2610
  // set a bit saying prologue has been called; cleared in epilogue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
  _between_prologue_and_epilogue = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
  // Claim locks for common data structures, then call gc_prologue_work()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2613
  // for each CMSGen and PermGen that we are responsible for.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2614
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2615
  getFreelistLocks();   // gets free list locks on constituent spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2616
  bitMapLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2617
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2618
  // Should call gc_prologue_work() for all cms gens we are responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2619
  bool registerClosure =    _collectorState >= Marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2620
                         && _collectorState < Sweeping;
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  2621
  ModUnionClosure* muc = CollectedHeap::use_parallel_gc_threads() ?
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  2622
                                               &_modUnionClosurePar
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2623
                                               : &_modUnionClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
  _cmsGen->gc_prologue_work(full, registerClosure, muc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
  _permGen->gc_prologue_work(full, registerClosure, muc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2626
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
  if (!full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2628
    stats().record_gc0_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2629
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2630
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2631
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
void ConcurrentMarkSweepGeneration::gc_prologue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2633
  // Delegate to CMScollector which knows how to coordinate between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2634
  // this and any other CMS generations that it is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2635
  // collecting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2636
  collector()->gc_prologue(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2637
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2638
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2639
// This is a "private" interface for use by this generation's CMSCollector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2640
// Not to be called directly by any other entity (for instance,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2641
// GenCollectedHeap, which calls the "public" gc_prologue method above).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2642
void ConcurrentMarkSweepGeneration::gc_prologue_work(bool full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2643
  bool registerClosure, ModUnionClosure* modUnionClosure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2644
  assert(!incremental_collection_failed(), "Shouldn't be set yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2645
  assert(cmsSpace()->preconsumptionDirtyCardClosure() == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2646
    "Should be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2647
  if (registerClosure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2648
    cmsSpace()->setPreconsumptionDirtyCardClosure(modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2649
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2650
  cmsSpace()->gc_prologue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2651
  // Clear stat counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2652
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2653
    assert(_numObjectsPromoted == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2654
    assert(_numWordsPromoted   == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2655
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2656
      gclog_or_tty->print("Allocated "SIZE_FORMAT" objects, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2657
                          SIZE_FORMAT" bytes concurrently",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2658
      _numObjectsAllocated, _numWordsAllocated*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2659
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2660
    _numObjectsAllocated = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2661
    _numWordsAllocated   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2662
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2663
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2664
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2665
void CMSCollector::gc_epilogue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2666
  // The following locking discipline assumes that we are only called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2667
  // when the world is stopped.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2668
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2669
         "world is stopped assumption");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2670
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2671
  // Currently the CMS epilogue (see CompactibleFreeListSpace) merely checks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2672
  // if linear allocation blocks need to be appropriately marked to allow the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2673
  // the blocks to be parsable. We also check here whether we need to nudge the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2674
  // CMS collector thread to start a new cycle (if it's not already active).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2675
  assert(   Thread::current()->is_VM_thread()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2676
         || (   CMSScavengeBeforeRemark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2677
             && Thread::current()->is_ConcurrentGC_thread()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2678
         "Incorrect thread type for epilogue execution");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2679
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2680
  if (!_between_prologue_and_epilogue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2681
    // We have already been invoked; this is a gc_epilogue delegation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2682
    // from yet another CMS generation that we are responsible for, just
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2683
    // ignore it since all relevant work has already been done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2684
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2685
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2686
  assert(haveFreelistLocks(), "must have freelist locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2687
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2688
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2689
  _cmsGen->gc_epilogue_work(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2690
  _permGen->gc_epilogue_work(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2691
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2692
  if (_collectorState == AbortablePreclean || _collectorState == Precleaning) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2693
    // in case sampling was not already enabled, enable it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2694
    _start_sampling = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2695
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2696
  // reset _eden_chunk_array so sampling starts afresh
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2697
  _eden_chunk_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2698
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2699
  size_t cms_used   = _cmsGen->cmsSpace()->used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2700
  size_t perm_used  = _permGen->cmsSpace()->used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2701
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2702
  // update performance counters - this uses a special version of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2703
  // update_counters() that allows the utilization to be passed as a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2704
  // parameter, avoiding multiple calls to used().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2705
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2706
  _cmsGen->update_counters(cms_used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2707
  _permGen->update_counters(perm_used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2708
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2709
  if (CMSIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2710
    icms_update_allocation_limits();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2711
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2712
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2713
  bitMapLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2714
  releaseFreelistLocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2715
10022
377345fb5fb5 7061204: clean the chunk table synchronously in embedded builds
jcoomes
parents: 9969
diff changeset
  2716
  if (!CleanChunkPoolAsync) {
377345fb5fb5 7061204: clean the chunk table synchronously in embedded builds
jcoomes
parents: 9969
diff changeset
  2717
    Chunk::clean_chunk_pool();
377345fb5fb5 7061204: clean the chunk table synchronously in embedded builds
jcoomes
parents: 9969
diff changeset
  2718
  }
377345fb5fb5 7061204: clean the chunk table synchronously in embedded builds
jcoomes
parents: 9969
diff changeset
  2719
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2720
  _between_prologue_and_epilogue = false;  // ready for next cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2721
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2722
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2723
void ConcurrentMarkSweepGeneration::gc_epilogue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2724
  collector()->gc_epilogue(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2725
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2726
  // Also reset promotion tracking in par gc thread states.
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  2727
  if (CollectedHeap::use_parallel_gc_threads()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2728
    for (uint i = 0; i < ParallelGCThreads; i++) {
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2729
      _par_gc_thread_states[i]->promo.stopTrackingPromotions(i);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2730
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2731
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2732
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2733
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2734
void ConcurrentMarkSweepGeneration::gc_epilogue_work(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2735
  assert(!incremental_collection_failed(), "Should have been cleared");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2736
  cmsSpace()->setPreconsumptionDirtyCardClosure(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2737
  cmsSpace()->gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2738
    // Print stat counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2739
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2740
    assert(_numObjectsAllocated == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2741
    assert(_numWordsAllocated == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2742
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2743
      gclog_or_tty->print("Promoted "SIZE_FORMAT" objects, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2744
                          SIZE_FORMAT" bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2745
                 _numObjectsPromoted, _numWordsPromoted*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2746
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2747
    _numObjectsPromoted = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2748
    _numWordsPromoted   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2749
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2750
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2751
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2752
    // Call down the chain in contiguous_available needs the freelistLock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2753
    // so print this out before releasing the freeListLock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2754
    gclog_or_tty->print(" Contiguous available "SIZE_FORMAT" bytes ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2755
                        contiguous_available());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2756
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2757
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2758
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2759
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2760
bool CMSCollector::have_cms_token() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2761
  Thread* thr = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2762
  if (thr->is_VM_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2763
    return ConcurrentMarkSweepThread::vm_thread_has_cms_token();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2764
  } else if (thr->is_ConcurrentGC_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2765
    return ConcurrentMarkSweepThread::cms_thread_has_cms_token();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2766
  } else if (thr->is_GC_task_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2767
    return ConcurrentMarkSweepThread::vm_thread_has_cms_token() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2768
           ParGCRareEvent_lock->owned_by_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2769
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2770
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2771
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2772
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2773
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2774
// Check reachability of the given heap address in CMS generation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2775
// treating all other generations as roots.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2776
bool CMSCollector::is_cms_reachable(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2777
  // We could "guarantee" below, rather than assert, but i'll
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2778
  // leave these as "asserts" so that an adventurous debugger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2779
  // could try this in the product build provided some subset of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2780
  // the conditions were met, provided they were intersted in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2781
  // results and knew that the computation below wouldn't interfere
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2782
  // with other concurrent computations mutating the structures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2783
  // being read or written.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2784
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2785
         "Else mutations in object graph will make answer suspect");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2786
  assert(have_cms_token(), "Should hold cms token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2787
  assert(haveFreelistLocks(), "must hold free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2788
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2789
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2790
  // Clear the marking bit map array before starting, but, just
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2791
  // for kicks, first report if the given address is already marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2792
  gclog_or_tty->print_cr("Start: Address 0x%x is%s marked", addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2793
                _markBitMap.isMarked(addr) ? "" : " not");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2794
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2795
  if (verify_after_remark()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2796
    MutexLockerEx x(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2797
    bool result = verification_mark_bm()->isMarked(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2798
    gclog_or_tty->print_cr("TransitiveMark: Address 0x%x %s marked", addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2799
                           result ? "IS" : "is NOT");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2800
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2801
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2802
    gclog_or_tty->print_cr("Could not compute result");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2803
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2804
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2805
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2806
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2807
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2808
// CMS Verification Support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2809
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2810
// Following the remark phase, the following invariant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2811
// should hold -- each object in the CMS heap which is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2812
// marked in markBitMap() should be marked in the verification_mark_bm().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2813
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2814
class VerifyMarkedClosure: public BitMapClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2815
  CMSBitMap* _marks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2816
  bool       _failed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2817
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2818
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2819
  VerifyMarkedClosure(CMSBitMap* bm): _marks(bm), _failed(false) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2820
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  2821
  bool do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2822
    HeapWord* addr = _marks->offsetToHeapWord(offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2823
    if (!_marks->isMarked(addr)) {
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2824
      oop(addr)->print_on(gclog_or_tty);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2825
      gclog_or_tty->print_cr(" ("INTPTR_FORMAT" should have been marked)", addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2826
      _failed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2827
    }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  2828
    return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2829
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2830
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2831
  bool failed() { return _failed; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2832
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2833
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2834
bool CMSCollector::verify_after_remark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2835
  gclog_or_tty->print(" [Verifying CMS Marking... ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2836
  MutexLockerEx ml(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2837
  static bool init = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2838
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2839
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2840
         "Else mutations in object graph will make answer suspect");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2841
  assert(have_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2842
         "Else there may be mutual interference in use of "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2843
         " verification data structures");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2844
  assert(_collectorState > Marking && _collectorState <= Sweeping,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2845
         "Else marking info checked here may be obsolete");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2846
  assert(haveFreelistLocks(), "must hold free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2847
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2848
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2849
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2850
  // Allocate marking bit map if not already allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2851
  if (!init) { // first time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2852
    if (!verification_mark_bm()->allocate(_span)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2853
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2854
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2855
    init = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2856
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2857
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2858
  assert(verification_mark_stack()->isEmpty(), "Should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2859
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2860
  // Turn off refs discovery -- so we will be tracing through refs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2861
  // This is as intended, because by this time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2862
  // GC must already have cleared any refs that need to be cleared,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2863
  // and traced those that need to be marked; moreover,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2864
  // the marking done here is not going to intefere in any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2865
  // way with the marking information used by GC.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2866
  NoRefDiscovery no_discovery(ref_processor());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2867
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2868
  COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2869
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2870
  // Clear any marks from a previous round
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2871
  verification_mark_bm()->clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2872
  assert(verification_mark_stack()->isEmpty(), "markStack should be empty");
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2873
  verify_work_stacks_empty();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2874
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2875
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2876
  gch->ensure_parsability(false);  // fill TLABs, but no need to retire them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2877
  // Update the saved marks which may affect the root scans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2878
  gch->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2879
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2880
  if (CMSRemarkVerifyVariant == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2881
    // In this first variant of verification, we complete
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2882
    // all marking, then check if the new marks-verctor is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2883
    // a subset of the CMS marks-vector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2884
    verify_after_remark_work_1();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2885
  } else if (CMSRemarkVerifyVariant == 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2886
    // In this second variant of verification, we flag an error
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2887
    // (i.e. an object reachable in the new marks-vector not reachable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2888
    // in the CMS marks-vector) immediately, also indicating the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2889
    // identify of an object (A) that references the unmarked object (B) --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2890
    // presumably, a mutation to A failed to be picked up by preclean/remark?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2891
    verify_after_remark_work_2();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2892
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2893
    warning("Unrecognized value %d for CMSRemarkVerifyVariant",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2894
            CMSRemarkVerifyVariant);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2895
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2896
  gclog_or_tty->print(" done] ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2897
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2898
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2899
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2900
void CMSCollector::verify_after_remark_work_1() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2901
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2902
  HandleMark  hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2903
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2904
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2905
  // Mark from roots one level into CMS
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  2906
  MarkRefsIntoClosure notOlder(_span, verification_mark_bm());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2907
  gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2908
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2909
  gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2910
                                true,   // younger gens are roots
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2911
                                true,   // activate StrongRootsScope
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2912
                                true,   // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2913
                                SharedHeap::ScanningOption(roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2914
                                &notOlder,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2915
                                true,   // walk code active on stacks
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2916
                                NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2917
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2918
  // Now mark from the roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2919
  assert(_revisitStack.isEmpty(), "Should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2920
  MarkFromRootsClosure markFromRootsClosure(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2921
    verification_mark_bm(), verification_mark_stack(), &_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2922
    false /* don't yield */, true /* verifying */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2923
  assert(_restart_addr == NULL, "Expected pre-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2924
  verification_mark_bm()->iterate(&markFromRootsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2925
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2926
    // Deal with stack overflow: by restarting at the indicated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2927
    // address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2928
    HeapWord* ra = _restart_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2929
    markFromRootsClosure.reset(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2930
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2931
    verification_mark_bm()->iterate(&markFromRootsClosure, ra, _span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2932
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2933
  assert(verification_mark_stack()->isEmpty(), "Should have been drained");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2934
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2935
  // Should reset the revisit stack above, since no class tree
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2936
  // surgery is forthcoming.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2937
  _revisitStack.reset(); // throwing away all contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2938
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2939
  // Marking completed -- now verify that each bit marked in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2940
  // verification_mark_bm() is also marked in markBitMap(); flag all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2941
  // errors by printing corresponding objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2942
  VerifyMarkedClosure vcl(markBitMap());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2943
  verification_mark_bm()->iterate(&vcl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2944
  if (vcl.failed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2945
    gclog_or_tty->print("Verification failed");
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2946
    Universe::heap()->print_on(gclog_or_tty);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2947
    fatal("CMS: failed marking verification after remark");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2948
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2949
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2950
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2951
void CMSCollector::verify_after_remark_work_2() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2952
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2953
  HandleMark  hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2954
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2955
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2956
  // Mark from roots one level into CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2957
  MarkRefsIntoVerifyClosure notOlder(_span, verification_mark_bm(),
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  2958
                                     markBitMap());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2959
  gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2960
  gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2961
                                true,   // younger gens are roots
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2962
                                true,   // activate StrongRootsScope
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2963
                                true,   // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2964
                                SharedHeap::ScanningOption(roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2965
                                &notOlder,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2966
                                true,   // walk code active on stacks
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2967
                                NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2968
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2969
  // Now mark from the roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2970
  assert(_revisitStack.isEmpty(), "Should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2971
  MarkFromRootsVerifyClosure markFromRootsClosure(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2972
    verification_mark_bm(), markBitMap(), verification_mark_stack());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2973
  assert(_restart_addr == NULL, "Expected pre-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2974
  verification_mark_bm()->iterate(&markFromRootsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2975
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2976
    // Deal with stack overflow: by restarting at the indicated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2977
    // address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2978
    HeapWord* ra = _restart_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2979
    markFromRootsClosure.reset(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2980
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2981
    verification_mark_bm()->iterate(&markFromRootsClosure, ra, _span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2982
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2983
  assert(verification_mark_stack()->isEmpty(), "Should have been drained");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2984
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2985
  // Should reset the revisit stack above, since no class tree
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2986
  // surgery is forthcoming.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2987
  _revisitStack.reset(); // throwing away all contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2988
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2989
  // Marking completed -- now verify that each bit marked in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2990
  // verification_mark_bm() is also marked in markBitMap(); flag all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2991
  // errors by printing corresponding objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2992
  VerifyMarkedClosure vcl(markBitMap());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2993
  verification_mark_bm()->iterate(&vcl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2994
  assert(!vcl.failed(), "Else verification above should not have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2995
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2996
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2997
void ConcurrentMarkSweepGeneration::save_marks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2998
  // delegate to CMS space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2999
  cmsSpace()->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3000
  for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3001
    _par_gc_thread_states[i]->promo.startTrackingPromotions();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3002
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3003
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3004
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3005
bool ConcurrentMarkSweepGeneration::no_allocs_since_save_marks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3006
  return cmsSpace()->no_allocs_since_save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3007
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3009
#define CMS_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix)    \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3010
                                                                \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3011
void ConcurrentMarkSweepGeneration::                            \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3012
oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) {   \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3013
  cl->set_generation(this);                                     \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3014
  cmsSpace()->oop_since_save_marks_iterate##nv_suffix(cl);      \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3015
  cl->reset_generation();                                       \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3016
  save_marks();                                                 \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3017
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3018
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3019
ALL_SINCE_SAVE_MARKS_CLOSURES(CMS_SINCE_SAVE_MARKS_DEFN)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3020
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3021
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3022
ConcurrentMarkSweepGeneration::object_iterate_since_last_GC(ObjectClosure* blk)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3023
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3024
  // Not currently implemented; need to do the following. -- ysr.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3025
  // dld -- I think that is used for some sort of allocation profiler.  So it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3026
  // really means the objects allocated by the mutator since the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3027
  // GC.  We could potentially implement this cheaply by recording only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3028
  // the direct allocations in a side data structure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3029
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3030
  // I think we probably ought not to be required to support these
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3031
  // iterations at any arbitrary point; I think there ought to be some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3032
  // call to enable/disable allocation profiling in a generation/space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3033
  // and the iterator ought to return the objects allocated in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3034
  // gen/space since the enable call, or the last iterator call (which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3035
  // will probably be at a GC.)  That way, for gens like CM&S that would
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3036
  // require some extra data structure to support this, we only pay the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3037
  // cost when it's in use...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3038
  cmsSpace()->object_iterate_since_last_GC(blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3039
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3040
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3041
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3042
ConcurrentMarkSweepGeneration::younger_refs_iterate(OopsInGenClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3043
  cl->set_generation(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3044
  younger_refs_in_space_iterate(_cmsSpace, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3045
  cl->reset_generation();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3046
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3047
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3048
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3049
ConcurrentMarkSweepGeneration::oop_iterate(MemRegion mr, OopClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3050
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3051
    Generation::oop_iterate(mr, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3052
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3053
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3054
    Generation::oop_iterate(mr, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3055
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3056
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3057
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3058
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3059
ConcurrentMarkSweepGeneration::oop_iterate(OopClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3060
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3061
    Generation::oop_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3062
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3063
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3064
    Generation::oop_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3065
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3066
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3067
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3068
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3069
ConcurrentMarkSweepGeneration::object_iterate(ObjectClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3070
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3071
    Generation::object_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3072
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3073
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3074
    Generation::object_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3075
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3076
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3077
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3078
void
1893
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3079
ConcurrentMarkSweepGeneration::safe_object_iterate(ObjectClosure* cl) {
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3080
  if (freelistLock()->owned_by_self()) {
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3081
    Generation::safe_object_iterate(cl);
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3082
  } else {
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3083
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3084
    Generation::safe_object_iterate(cl);
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3085
  }
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3086
}
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3087
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3088
void
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3089
ConcurrentMarkSweepGeneration::pre_adjust_pointers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3090
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3091
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3092
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3093
ConcurrentMarkSweepGeneration::post_compact() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3094
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3095
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3096
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3097
ConcurrentMarkSweepGeneration::prepare_for_verify() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3098
  // Fix the linear allocation blocks to look like free blocks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3099
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3100
  // Locks are normally acquired/released in gc_prologue/gc_epilogue, but those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3101
  // are not called when the heap is verified during universe initialization and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3102
  // at vm shutdown.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3103
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3104
    cmsSpace()->prepare_for_verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3105
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3106
    MutexLockerEx fll(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3107
    cmsSpace()->prepare_for_verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3108
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3109
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3110
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3111
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3112
ConcurrentMarkSweepGeneration::verify(bool allow_dirty /* ignored */) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3113
  // Locks are normally acquired/released in gc_prologue/gc_epilogue, but those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3114
  // are not called when the heap is verified during universe initialization and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3115
  // at vm shutdown.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3116
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3117
    cmsSpace()->verify(false /* ignored */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3118
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3119
    MutexLockerEx fll(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3120
    cmsSpace()->verify(false /* ignored */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3121
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3122
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3123
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3124
void CMSCollector::verify(bool allow_dirty /* ignored */) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3125
  _cmsGen->verify(allow_dirty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3126
  _permGen->verify(allow_dirty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3127
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3128
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3129
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3130
bool CMSCollector::overflow_list_is_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3131
  assert(_num_par_pushes >= 0, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3132
  if (_overflow_list == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3133
    assert(_num_par_pushes == 0, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3134
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3135
  return _overflow_list == NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3136
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3137
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3138
// The methods verify_work_stacks_empty() and verify_overflow_empty()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3139
// merely consolidate assertion checks that appear to occur together frequently.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3140
void CMSCollector::verify_work_stacks_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3141
  assert(_markStack.isEmpty(), "Marking stack should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3142
  assert(overflow_list_is_empty(), "Overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3143
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3144
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3145
void CMSCollector::verify_overflow_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3146
  assert(overflow_list_is_empty(), "Overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3147
  assert(no_preserved_marks(), "No preserved marks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3148
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3149
#endif // PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3150
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3151
// Decide if we want to enable class unloading as part of the
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3152
// ensuing concurrent GC cycle. We will collect the perm gen and
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3153
// unload classes if it's the case that:
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3154
// (1) an explicit gc request has been made and the flag
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3155
//     ExplicitGCInvokesConcurrentAndUnloadsClasses is set, OR
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3156
// (2) (a) class unloading is enabled at the command line, and
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3157
//     (b) (i)   perm gen threshold has been crossed, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3158
//         (ii)  old gen is getting really full, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3159
//         (iii) the previous N CMS collections did not collect the
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3160
//               perm gen
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3161
// NOTE: Provided there is no change in the state of the heap between
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3162
// calls to this method, it should have idempotent results. Moreover,
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3163
// its results should be monotonically increasing (i.e. going from 0 to 1,
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3164
// but not 1 to 0) between successive calls between which the heap was
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3165
// not collected. For the implementation below, it must thus rely on
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3166
// the property that concurrent_cycles_since_last_unload()
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3167
// will not decrease unless a collection cycle happened and that
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3168
// _permGen->should_concurrent_collect() and _cmsGen->is_too_full() are
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3169
// themselves also monotonic in that sense. See check_monotonicity()
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3170
// below.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3171
bool CMSCollector::update_should_unload_classes() {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3172
  _should_unload_classes = false;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3173
  // Condition 1 above
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3174
  if (_full_gc_requested && ExplicitGCInvokesConcurrentAndUnloadsClasses) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3175
    _should_unload_classes = true;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3176
  } else if (CMSClassUnloadingEnabled) { // Condition 2.a above
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3177
    // Disjuncts 2.b.(i,ii,iii) above
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3178
    _should_unload_classes = (concurrent_cycles_since_last_unload() >=
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3179
                              CMSClassUnloadingMaxInterval)
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3180
                           || _permGen->should_concurrent_collect()
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3181
                           || _cmsGen->is_too_full();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3182
  }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3183
  return _should_unload_classes;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3184
}
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3185
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3186
bool ConcurrentMarkSweepGeneration::is_too_full() const {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3187
  bool res = should_concurrent_collect();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3188
  res = res && (occupancy() > (double)CMSIsTooFullPercentage/100.0);
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3189
  return res;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3190
}
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3191
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3192
void CMSCollector::setup_cms_unloading_and_verification_state() {
9342
456b8d0486b5 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 8728
diff changeset
  3193
  const  bool should_verify =   VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3194
                             || VerifyBeforeExit;
9342
456b8d0486b5 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 8728
diff changeset
  3195
  const  int  rso           =   SharedHeap::SO_Strings | SharedHeap::SO_CodeCache;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3196
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3197
  if (should_unload_classes()) {   // Should unload classes this cycle
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3198
    remove_root_scanning_option(rso);  // Shrink the root set appropriately
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3199
    set_verifying(should_verify);    // Set verification state for this cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3200
    return;                            // Nothing else needs to be done at this time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3201
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3202
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3203
  // Not unloading classes this cycle
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3204
  assert(!should_unload_classes(), "Inconsitency!");
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3205
  if ((!verifying() || unloaded_classes_last_cycle()) && should_verify) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3206
    // We were not verifying, or we _were_ unloading classes in the last cycle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3207
    // AND some verification options are enabled this cycle; in this case,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3208
    // we must make sure that the deadness map is allocated if not already so,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3209
    // and cleared (if already allocated previously --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3210
    // CMSBitMap::sizeInBits() is used to determine if it's allocated).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3211
    if (perm_gen_verify_bit_map()->sizeInBits() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3212
      if (!perm_gen_verify_bit_map()->allocate(_permGen->reserved())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3213
        warning("Failed to allocate permanent generation verification CMS Bit Map;\n"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3214
                "permanent generation verification disabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3215
        return;  // Note that we leave verification disabled, so we'll retry this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3216
                 // allocation next cycle. We _could_ remember this failure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3217
                 // and skip further attempts and permanently disable verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3218
                 // attempts if that is considered more desirable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3219
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3220
      assert(perm_gen_verify_bit_map()->covers(_permGen->reserved()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3221
              "_perm_gen_ver_bit_map inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3222
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3223
      perm_gen_verify_bit_map()->clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3224
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3225
    // Include symbols, strings and code cache elements to prevent their resurrection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3226
    add_root_scanning_option(rso);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3227
    set_verifying(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3228
  } else if (verifying() && !should_verify) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3229
    // We were verifying, but some verification flags got disabled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3230
    set_verifying(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3231
    // Exclude symbols, strings and code cache elements from root scanning to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3232
    // reduce IM and RM pauses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3233
    remove_root_scanning_option(rso);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3234
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3235
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3236
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3237
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3238
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3239
HeapWord* CMSCollector::block_start(const void* p) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3240
  const HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3241
  if (_span.contains(p)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3242
    if (_cmsGen->cmsSpace()->is_in_reserved(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3243
      return _cmsGen->cmsSpace()->block_start(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3244
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3245
      assert(_permGen->cmsSpace()->is_in_reserved(addr),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3246
             "Inconsistent _span?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3247
      return _permGen->cmsSpace()->block_start(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3248
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3249
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3250
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3251
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3252
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3253
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3254
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3255
ConcurrentMarkSweepGeneration::expand_and_allocate(size_t word_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3256
                                                   bool   tlab,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3257
                                                   bool   parallel) {
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3258
  CMSSynchronousYieldRequest yr;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3259
  assert(!tlab, "Can't deal with TLAB allocation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3260
  MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3261
  expand(word_size*HeapWordSize, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3262
    CMSExpansionCause::_satisfy_allocation);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3263
  if (GCExpandToAllocateDelayMillis > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3264
    os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3265
  }
182
eae79d9b9d46 6642634: Test nsk/regression/b6186200 crashed with SIGSEGV
ysr
parents: 180
diff changeset
  3266
  return have_lock_and_allocate(word_size, tlab);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3267
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3268
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3269
// YSR: All of this generation expansion/shrinking stuff is an exact copy of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3270
// OneContigSpaceCardGeneration, which makes me wonder if we should move this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3271
// to CardGeneration and share it...
979
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3272
bool ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes) {
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3273
  return CardGeneration::expand(bytes, expand_bytes);
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3274
}
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3275
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3276
void ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3277
  CMSExpansionCause::Cause cause)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3278
{
979
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3279
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3280
  bool success = expand(bytes, expand_bytes);
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3281
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3282
  // remember why we expanded; this information is used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3283
  // by shouldConcurrentCollect() when making decisions on whether to start
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3284
  // a new CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3285
  if (success) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3286
    set_expansion_cause(cause);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3287
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3288
      gclog_or_tty->print_cr("Expanded CMS gen for %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3289
        CMSExpansionCause::to_string(cause));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3290
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3291
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3292
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3293
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3294
HeapWord* ConcurrentMarkSweepGeneration::expand_and_par_lab_allocate(CMSParGCThreadState* ps, size_t word_sz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3295
  HeapWord* res = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3296
  MutexLocker x(ParGCRareEvent_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3297
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3298
    // Expansion by some other thread might make alloc OK now:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3299
    res = ps->lab.alloc(word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3300
    if (res != NULL) return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3301
    // If there's not enough expansion space available, give up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3302
    if (_virtual_space.uncommitted_size() < (word_sz * HeapWordSize)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3303
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3304
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3305
    // Otherwise, we try expansion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3306
    expand(word_sz*HeapWordSize, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3307
      CMSExpansionCause::_allocate_par_lab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3308
    // Now go around the loop and try alloc again;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3309
    // A competing par_promote might beat us to the expansion space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3310
    // so we may go around the loop again if promotion fails agaion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3311
    if (GCExpandToAllocateDelayMillis > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3312
      os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3313
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3314
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3315
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3316
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3317
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3318
bool ConcurrentMarkSweepGeneration::expand_and_ensure_spooling_space(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3319
  PromotionInfo* promo) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3320
  MutexLocker x(ParGCRareEvent_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3321
  size_t refill_size_bytes = promo->refillSize() * HeapWordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3322
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3323
    // Expansion by some other thread might make alloc OK now:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3324
    if (promo->ensure_spooling_space()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3325
      assert(promo->has_spooling_space(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3326
             "Post-condition of successful ensure_spooling_space()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3327
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3328
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3329
    // If there's not enough expansion space available, give up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3330
    if (_virtual_space.uncommitted_size() < refill_size_bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3331
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3332
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3333
    // Otherwise, we try expansion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3334
    expand(refill_size_bytes, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3335
      CMSExpansionCause::_allocate_par_spooling_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3336
    // Now go around the loop and try alloc again;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3337
    // A competing allocation might beat us to the expansion space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3338
    // so we may go around the loop again if allocation fails again.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3339
    if (GCExpandToAllocateDelayMillis > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3340
      os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3341
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3342
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3343
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3344
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3345
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3346
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3347
void ConcurrentMarkSweepGeneration::shrink(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3348
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3349
  size_t size = ReservedSpace::page_align_size_down(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3350
  if (size > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3351
    shrink_by(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3352
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3353
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3354
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3355
bool ConcurrentMarkSweepGeneration::grow_by(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3356
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3357
  bool result = _virtual_space.expand_by(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3358
  if (result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3359
    HeapWord* old_end = _cmsSpace->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3360
    size_t new_word_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3361
      heap_word_size(_virtual_space.committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3362
    MemRegion mr(_cmsSpace->bottom(), new_word_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3363
    _bts->resize(new_word_size);  // resize the block offset shared array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3364
    Universe::heap()->barrier_set()->resize_covered_region(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3365
    // Hmmmm... why doesn't CFLS::set_end verify locking?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3366
    // This is quite ugly; FIX ME XXX
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  3367
    _cmsSpace->assert_locked(freelistLock());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3368
    _cmsSpace->set_end((HeapWord*)_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3369
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3370
    // update the space and generation capacity counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3371
    if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3372
      _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3373
      _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3374
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3375
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3376
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3377
      size_t new_mem_size = _virtual_space.committed_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3378
      size_t old_mem_size = new_mem_size - bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3379
      gclog_or_tty->print_cr("Expanding %s from %ldK by %ldK to %ldK",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3380
                    name(), old_mem_size/K, bytes/K, new_mem_size/K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3381
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3382
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3383
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3384
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3385
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3386
bool ConcurrentMarkSweepGeneration::grow_to_reserved() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3387
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3388
  bool success = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3389
  const size_t remaining_bytes = _virtual_space.uncommitted_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3390
  if (remaining_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3391
    success = grow_by(remaining_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3392
    DEBUG_ONLY(if (!success) warning("grow to reserved failed");)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3393
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3394
  return success;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3395
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3396
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3397
void ConcurrentMarkSweepGeneration::shrink_by(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3398
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3399
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3400
  // XXX Fix when compaction is implemented.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3401
  warning("Shrinking of CMS not yet implemented");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3402
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3403
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3404
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3405
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3406
// Simple ctor/dtor wrapper for accounting & timer chores around concurrent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3407
// phases.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3408
class CMSPhaseAccounting: public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3409
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3410
  CMSPhaseAccounting(CMSCollector *collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3411
                     const char *phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3412
                     bool print_cr = true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3413
  ~CMSPhaseAccounting();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3414
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3415
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3416
  CMSCollector *_collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3417
  const char *_phase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3418
  elapsedTimer _wallclock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3419
  bool _print_cr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3420
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3421
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3422
  // Not MT-safe; so do not pass around these StackObj's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3423
  // where they may be accessed by other threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3424
  jlong wallclock_millis() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3425
    assert(_wallclock.is_active(), "Wall clock should not stop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3426
    _wallclock.stop();  // to record time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3427
    jlong ret = _wallclock.milliseconds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3428
    _wallclock.start(); // restart
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3429
    return ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3430
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3431
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3432
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3433
CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3434
                                       const char *phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3435
                                       bool print_cr) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3436
  _collector(collector), _phase(phase), _print_cr(print_cr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3437
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3438
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3439
    _collector->resetYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3440
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3441
  if (PrintGCDetails && PrintGCTimeStamps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3442
    gclog_or_tty->date_stamp(PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3443
    gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3444
    gclog_or_tty->print_cr(": [%s-concurrent-%s-start]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3445
      _collector->cmsGen()->short_name(), _phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3446
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3447
  _collector->resetTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3448
  _wallclock.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3449
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3450
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3451
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3452
CMSPhaseAccounting::~CMSPhaseAccounting() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3453
  assert(_wallclock.is_active(), "Wall clock should not have stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3454
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3455
  _wallclock.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3456
  if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3457
    gclog_or_tty->date_stamp(PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3458
    if (PrintGCTimeStamps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3459
      gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3460
      gclog_or_tty->print(": ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3461
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3462
    gclog_or_tty->print("[%s-concurrent-%s: %3.3f/%3.3f secs]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3463
                 _collector->cmsGen()->short_name(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3464
                 _phase, _collector->timerValue(), _wallclock.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3465
    if (_print_cr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3466
      gclog_or_tty->print_cr("");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3467
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3468
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3469
      gclog_or_tty->print_cr(" (CMS-concurrent-%s yielded %d times)", _phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3470
                    _collector->yields());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3471
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3472
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3473
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3474
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3475
// CMS work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3476
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3477
// Checkpoint the roots into this generation from outside
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3478
// this generation. [Note this initial checkpoint need only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3479
// be approximate -- we'll do a catch up phase subsequently.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3480
void CMSCollector::checkpointRootsInitial(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3481
  assert(_collectorState == InitialMarking, "Wrong collector state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3482
  check_correct_thread_executing();
9623
151c0b638488 7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents: 9342
diff changeset
  3483
  TraceCMSMemoryManagerStats tms(_collectorState,GenCollectedHeap::heap()->gc_cause());
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7419
diff changeset
  3484
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3485
  ReferenceProcessor* rp = ref_processor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3486
  SpecializationStats::clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3487
  assert(_restart_addr == NULL, "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3488
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3489
    // acquire locks for subsequent manipulations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3490
    MutexLockerEx x(bitMapLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3491
                    Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3492
    checkpointRootsInitialWork(asynch);
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10240
diff changeset
  3493
    // enable ("weak") refs discovery
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10240
diff changeset
  3494
    rp->enable_discovery(true /*verify_disabled*/, true /*check_no_refs*/);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3495
    _collectorState = Marking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3496
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3497
    // (Weak) Refs discovery: this is controlled from genCollectedHeap::do_collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3498
    // which recognizes if we are a CMS generation, and doesn't try to turn on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3499
    // discovery; verify that they aren't meddling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3500
    assert(!rp->discovery_is_atomic(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3501
           "incorrect setting of discovery predicate");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3502
    assert(!rp->discovery_enabled(), "genCollectedHeap shouldn't control "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3503
           "ref discovery for this generation kind");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3504
    // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3505
    checkpointRootsInitialWork(asynch);
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10240
diff changeset
  3506
    // now enable ("weak") refs discovery
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10240
diff changeset
  3507
    rp->enable_discovery(true /*verify_disabled*/, false /*verify_no_refs*/);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3508
    _collectorState = Marking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3509
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3510
  SpecializationStats::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3511
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3512
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3513
void CMSCollector::checkpointRootsInitialWork(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3514
  assert(SafepointSynchronize::is_at_safepoint(), "world should be stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3515
  assert(_collectorState == InitialMarking, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3516
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3517
  // If there has not been a GC[n-1] since last GC[n] cycle completed,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3518
  // precede our marking with a collection of all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3519
  // younger generations to keep floating garbage to a minimum.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3520
  // XXX: we won't do this for now -- it's an optimization to be done later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3521
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3522
  // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3523
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3524
  assert(_markBitMap.isAllClear(), "was reset at end of previous cycle");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3525
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3526
  // Setup the verification and class unloading state for this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3527
  // CMS collection cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3528
  setup_cms_unloading_and_verification_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3529
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3530
  NOT_PRODUCT(TraceTime t("\ncheckpointRootsInitialWork",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3531
    PrintGCDetails && Verbose, true, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3532
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3533
    size_policy()->checkpoint_roots_initial_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3534
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3536
  // Reset all the PLAB chunk arrays if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3537
  if (_survivor_plab_array != NULL && !CMSPLABRecordAlways) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3538
    reset_survivor_plab_arrays();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3539
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3540
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3541
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3542
  HandleMark  hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3543
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3544
  FalseClosure falseClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3545
  // In the case of a synchronous collection, we will elide the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3546
  // remark step, so it's important to catch all the nmethod oops
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  3547
  // in this step.
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  3548
  // The final 'true' flag to gen_process_strong_roots will ensure this.
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  3549
  // If 'async' is true, we can relax the nmethod tracing.
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  3550
  MarkRefsIntoClosure notOlder(_span, &_markBitMap);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3551
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3552
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3553
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3554
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3555
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3556
  gch->ensure_parsability(false);  // fill TLABs, but no need to retire them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3557
  // Update the saved marks which may affect the root scans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3558
  gch->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3559
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3560
  // weak reference processing has not started yet.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3561
  ref_processor()->set_enqueuing_is_done(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3562
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3563
  {
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  3564
    // This is not needed. DEBUG_ONLY(RememberKlassesChecker imx(true);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3565
    COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3566
    gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3567
    gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3568
                                  true,   // younger gens are roots
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  3569
                                  true,   // activate StrongRootsScope
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3570
                                  true,   // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3571
                                  SharedHeap::ScanningOption(roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  3572
                                  &notOlder,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  3573
                                  true,   // walk all of code cache if (so & SO_CodeCache)
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  3574
                                  NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3575
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3576
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3577
  // Clear mod-union table; it will be dirtied in the prologue of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3578
  // CMS generation per each younger generation collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3579
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3580
  assert(_modUnionTable.isAllClear(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3581
       "Was cleared in most recent final checkpoint phase"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3582
       " or no bits are set in the gc_prologue before the start of the next "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3583
       "subsequent marking phase.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3584
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3585
  // Temporarily disabled, since pre/post-consumption closures don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3586
  // care about precleaned cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3587
  #if 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3588
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3589
    MemRegion mr = MemRegion((HeapWord*)_virtual_space.low(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3590
                             (HeapWord*)_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3591
    _ct->ct_bs()->preclean_dirty_cards(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3592
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3593
  #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3594
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3595
  // Save the end of the used_region of the constituent generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3596
  // to be used to limit the extent of sweep in each generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3597
  save_sweep_limits();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3598
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3599
    size_policy()->checkpoint_roots_initial_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3600
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3601
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3602
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3603
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3604
bool CMSCollector::markFromRoots(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3605
  // we might be tempted to assert that:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3606
  // assert(asynch == !SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3607
  //        "inconsistent argument?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3608
  // However that wouldn't be right, because it's possible that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3609
  // a safepoint is indeed in progress as a younger generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3610
  // stop-the-world GC happens even as we mark in this generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3611
  assert(_collectorState == Marking, "inconsistent state?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3612
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3613
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3614
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3615
  bool res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3616
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3617
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3618
    // Start the timers for adaptive size policy for the concurrent phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3619
    // Do it here so that the foreground MS can use the concurrent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3620
    // timer since a foreground MS might has the sweep done concurrently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3621
    // or STW.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3622
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3623
      size_policy()->concurrent_marking_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3624
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3625
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3626
    // Weak ref discovery note: We may be discovering weak
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3627
    // refs in this generation concurrent (but interleaved) with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3628
    // weak ref discovery by a younger generation collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3629
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3630
    CMSTokenSyncWithLocks ts(true, bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3631
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3632
    CMSPhaseAccounting pa(this, "mark", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3633
    res = markFromRootsWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3634
    if (res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3635
      _collectorState = Precleaning;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3636
    } else { // We failed and a foreground collection wants to take over
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3637
      assert(_foregroundGCIsActive, "internal state inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3638
      assert(_restart_addr == NULL,  "foreground will restart from scratch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3639
      if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3640
        gclog_or_tty->print_cr("bailing out to foreground collection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3641
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3642
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3643
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3644
      size_policy()->concurrent_marking_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3645
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3646
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3647
    assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3648
           "inconsistent with asynch == false");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3649
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3650
      size_policy()->ms_collection_marking_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3651
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3652
    // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3653
    res = markFromRootsWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3654
    _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3655
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3656
      GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3657
      size_policy()->ms_collection_marking_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3658
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3659
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3660
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3661
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3662
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3663
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3664
bool CMSCollector::markFromRootsWork(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3665
  // iterate over marked bits in bit map, doing a full scan and mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3666
  // from these roots using the following algorithm:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3667
  // . if oop is to the right of the current scan pointer,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3668
  //   mark corresponding bit (we'll process it later)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3669
  // . else (oop is to left of current scan pointer)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3670
  //   push oop on marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3671
  // . drain the marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3672
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3673
  // Note that when we do a marking step we need to hold the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3674
  // bit map lock -- recall that direct allocation (by mutators)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3675
  // and promotion (by younger generation collectors) is also
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3676
  // marking the bit map. [the so-called allocate live policy.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3677
  // Because the implementation of bit map marking is not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3678
  // robust wrt simultaneous marking of bits in the same word,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3679
  // we need to make sure that there is no such interference
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3680
  // between concurrent such updates.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3681
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3682
  // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3683
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3684
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3685
  // Clear the revisit stack, just in case there are any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3686
  // obsolete contents from a short-circuited previous CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3687
  _revisitStack.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3688
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3689
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3690
  assert(_revisitStack.isEmpty(), "tabula rasa");
4738
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4574
diff changeset
  3691
  DEBUG_ONLY(RememberKlassesChecker cmx(should_unload_classes());)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3692
  bool result = false;
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
  3693
  if (CMSConcurrentMTEnabled && ConcGCThreads > 0) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3694
    result = do_marking_mt(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3695
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3696
    result = do_marking_st(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3697
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3698
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3699
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3700
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3701
// Forward decl
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3702
class CMSConcMarkingTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3703
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3704
class CMSConcMarkingTerminator: public ParallelTaskTerminator {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3705
  CMSCollector*       _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3706
  CMSConcMarkingTask* _task;
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3707
 public:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3708
  virtual void yield();
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3709
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3710
  // "n_threads" is the number of threads to be terminated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3711
  // "queue_set" is a set of work queues of other threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3712
  // "collector" is the CMS collector associated with this task terminator.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3713
  // "yield" indicates whether we need the gang as a whole to yield.
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3714
  CMSConcMarkingTerminator(int n_threads, TaskQueueSetSuper* queue_set, CMSCollector* collector) :
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3715
    ParallelTaskTerminator(n_threads, queue_set),
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3716
    _collector(collector) { }
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3717
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3718
  void set_task(CMSConcMarkingTask* task) {
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3719
    _task = task;
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3720
  }
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3721
};
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3722
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3723
class CMSConcMarkingTerminatorTerminator: public TerminatorTerminator {
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3724
  CMSConcMarkingTask* _task;
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3725
 public:
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3726
  bool should_exit_termination();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3727
  void set_task(CMSConcMarkingTask* task) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3728
    _task = task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3729
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3730
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3731
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3732
// MT Concurrent Marking Task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3733
class CMSConcMarkingTask: public YieldingFlexibleGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3734
  CMSCollector* _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3735
  int           _n_workers;                  // requested/desired # workers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3736
  bool          _asynch;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3737
  bool          _result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3738
  CompactibleFreeListSpace*  _cms_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3739
  CompactibleFreeListSpace* _perm_space;
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3740
  char          _pad_front[64];   // padding to ...
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3741
  HeapWord*     _global_finger;   // ... avoid sharing cache line
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3742
  char          _pad_back[64];
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3743
  HeapWord*     _restart_addr;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3744
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3745
  //  Exposed here for yielding support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3746
  Mutex* const _bit_map_lock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3747
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3748
  // The per thread work queues, available here for stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3749
  OopTaskQueueSet*  _task_queues;
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3750
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3751
  // Termination (and yielding) support
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3752
  CMSConcMarkingTerminator _term;
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3753
  CMSConcMarkingTerminatorTerminator _term_term;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3754
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3755
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3756
  CMSConcMarkingTask(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3757
                 CompactibleFreeListSpace* cms_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3758
                 CompactibleFreeListSpace* perm_space,
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  3759
                 bool asynch,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3760
                 YieldingFlexibleWorkGang* workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3761
                 OopTaskQueueSet* task_queues):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3762
    YieldingFlexibleGangTask("Concurrent marking done multi-threaded"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3763
    _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3764
    _cms_space(cms_space),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3765
    _perm_space(perm_space),
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  3766
    _asynch(asynch), _n_workers(0), _result(true),
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  3767
    _task_queues(task_queues),
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3768
    _term(_n_workers, task_queues, _collector),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3769
    _bit_map_lock(collector->bitMapLock())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3770
  {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  3771
    _requested_size = _n_workers;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3772
    _term.set_task(this);
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3773
    _term_term.set_task(this);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3774
    assert(_cms_space->bottom() < _perm_space->bottom(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3775
           "Finger incorrectly initialized below");
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3776
    _restart_addr = _global_finger = _cms_space->bottom();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3777
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3778
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3779
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3780
  OopTaskQueueSet* task_queues()  { return _task_queues; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3781
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3782
  OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3784
  HeapWord** global_finger_addr() { return &_global_finger; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3785
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3786
  CMSConcMarkingTerminator* terminator() { return &_term; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3787
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  3788
  virtual void set_for_termination(int active_workers) {
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  3789
    terminator()->reset_for_reuse(active_workers);
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  3790
  }
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  3791
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3792
  void work(int i);
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3793
  bool should_yield() {
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3794
    return    ConcurrentMarkSweepThread::should_yield()
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3795
           && !_collector->foregroundGCIsActive()
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3796
           && _asynch;
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3797
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3798
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3799
  virtual void coordinator_yield();  // stuff done by coordinator
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3800
  bool result() { return _result; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3801
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3802
  void reset(HeapWord* ra) {
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3803
    assert(_global_finger >= _cms_space->end(),  "Postcondition of ::work(i)");
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3804
    assert(_global_finger >= _perm_space->end(), "Postcondition of ::work(i)");
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3805
    assert(ra             <  _perm_space->end(), "ra too large");
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3806
    _restart_addr = _global_finger = ra;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3807
    _term.reset_for_reuse();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3808
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3809
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3810
  static bool get_work_from_overflow_stack(CMSMarkStack* ovflw_stk,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3811
                                           OopTaskQueue* work_q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3812
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3813
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3814
  void do_scan_and_mark(int i, CompactibleFreeListSpace* sp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3815
  void do_work_steal(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3816
  void bump_global_finger(HeapWord* f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3817
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3818
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3819
bool CMSConcMarkingTerminatorTerminator::should_exit_termination() {
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3820
  assert(_task != NULL, "Error");
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3821
  return _task->yielding();
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3822
  // Note that we do not need the disjunct || _task->should_yield() above
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3823
  // because we want terminating threads to yield only if the task
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3824
  // is already in the midst of yielding, which happens only after at least one
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3825
  // thread has yielded.
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3826
}
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3827
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3828
void CMSConcMarkingTerminator::yield() {
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  3829
  if (_task->should_yield()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3830
    _task->yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3831
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3832
    ParallelTaskTerminator::yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3833
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3834
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3835
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3836
////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3837
// Concurrent Marking Algorithm Sketch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3838
////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3839
// Until all tasks exhausted (both spaces):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3840
// -- claim next available chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3841
// -- bump global finger via CAS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3842
// -- find first object that starts in this chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3843
//    and start scanning bitmap from that position
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3844
// -- scan marked objects for oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3845
// -- CAS-mark target, and if successful:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3846
//    . if target oop is above global finger (volatile read)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3847
//      nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3848
//    . if target oop is in chunk and above local finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3849
//        then nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3850
//    . else push on work-queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3851
// -- Deal with possible overflow issues:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3852
//    . local work-queue overflow causes stuff to be pushed on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3853
//      global (common) overflow queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3854
//    . always first empty local work queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3855
//    . then get a batch of oops from global work queue if any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3856
//    . then do work stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3857
// -- When all tasks claimed (both spaces)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3858
//    and local work queue empty,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3859
//    then in a loop do:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3860
//    . check global overflow stack; steal a batch of oops and trace
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3861
//    . try to steal from other threads oif GOS is empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3862
//    . if neither is available, offer termination
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3863
// -- Terminate and return result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3864
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3865
void CMSConcMarkingTask::work(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3866
  elapsedTimer _timer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3867
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3868
  HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3869
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3870
  DEBUG_ONLY(_collector->verify_overflow_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3871
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3872
  // Before we begin work, our work queue should be empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3873
  assert(work_queue(i)->size() == 0, "Expected to be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3874
  // Scan the bitmap covering _cms_space, tracing through grey objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3875
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3876
  do_scan_and_mark(i, _cms_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3877
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3878
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3879
    gclog_or_tty->print_cr("Finished cms space scanning in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3880
      i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3881
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3882
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3883
  // ... do the same for the _perm_space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3884
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3885
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3886
  do_scan_and_mark(i, _perm_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3887
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3888
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3889
    gclog_or_tty->print_cr("Finished perm space scanning in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3890
      i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3891
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3892
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3893
  // ... do work stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3894
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3895
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3896
  do_work_steal(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3897
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3898
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3899
    gclog_or_tty->print_cr("Finished work stealing in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3900
      i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3901
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3902
  assert(_collector->_markStack.isEmpty(), "Should have been emptied");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3903
  assert(work_queue(i)->size() == 0, "Should have been emptied");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3904
  // Note that under the current task protocol, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3905
  // following assertion is true even of the spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3906
  // expanded since the completion of the concurrent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3907
  // marking. XXX This will likely change under a strict
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3908
  // ABORT semantics.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3909
  assert(_global_finger >  _cms_space->end() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3910
         _global_finger >= _perm_space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3911
         "All tasks have been completed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3912
  DEBUG_ONLY(_collector->verify_overflow_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3913
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3914
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3915
void CMSConcMarkingTask::bump_global_finger(HeapWord* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3916
  HeapWord* read = _global_finger;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3917
  HeapWord* cur  = read;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3918
  while (f > read) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3919
    cur = read;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3920
    read = (HeapWord*) Atomic::cmpxchg_ptr(f, &_global_finger, cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3921
    if (cur == read) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3922
      // our cas succeeded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3923
      assert(_global_finger >= f, "protocol consistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3924
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3925
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3926
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3927
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3928
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3929
// This is really inefficient, and should be redone by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3930
// using (not yet available) block-read and -write interfaces to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3931
// stack and the work_queue. XXX FIX ME !!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3932
bool CMSConcMarkingTask::get_work_from_overflow_stack(CMSMarkStack* ovflw_stk,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3933
                                                      OopTaskQueue* work_q) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3934
  // Fast lock-free check
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3935
  if (ovflw_stk->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3936
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3937
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3938
  assert(work_q->size() == 0, "Shouldn't steal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3939
  MutexLockerEx ml(ovflw_stk->par_lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3940
                   Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3941
  // Grab up to 1/4 the size of the work queue
2346
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  3942
  size_t num = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3943
                    (size_t)ParGCDesiredObjsFromOverflowList);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3944
  num = MIN2(num, ovflw_stk->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3945
  for (int i = (int) num; i > 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3946
    oop cur = ovflw_stk->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3947
    assert(cur != NULL, "Counted wrong?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3948
    work_q->push(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3949
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3950
  return num > 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3951
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3952
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3953
void CMSConcMarkingTask::do_scan_and_mark(int i, CompactibleFreeListSpace* sp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3954
  SequentialSubTasksDone* pst = sp->conc_par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3955
  int n_tasks = pst->n_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3956
  // We allow that there may be no tasks to do here because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3957
  // we are restarting after a stack overflow.
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3958
  assert(pst->valid() || n_tasks == 0, "Uninitialized use?");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3959
  int nth_task = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3960
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3961
  HeapWord* aligned_start = sp->bottom();
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3962
  if (sp->used_region().contains(_restart_addr)) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3963
    // Align down to a card boundary for the start of 0th task
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3964
    // for this space.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3965
    aligned_start =
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3966
      (HeapWord*)align_size_down((uintptr_t)_restart_addr,
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3967
                                 CardTableModRefBS::card_size);
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3968
  }
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3969
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3970
  size_t chunk_size = sp->marking_task_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3971
  while (!pst->is_task_claimed(/* reference */ nth_task)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3972
    // Having claimed the nth task in this space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3973
    // compute the chunk that it corresponds to:
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3974
    MemRegion span = MemRegion(aligned_start + nth_task*chunk_size,
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3975
                               aligned_start + (nth_task+1)*chunk_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3976
    // Try and bump the global finger via a CAS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3977
    // note that we need to do the global finger bump
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3978
    // _before_ taking the intersection below, because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3979
    // the task corresponding to that region will be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3980
    // deemed done even if the used_region() expands
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3981
    // because of allocation -- as it almost certainly will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3982
    // during start-up while the threads yield in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3983
    // closure below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3984
    HeapWord* finger = span.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3985
    bump_global_finger(finger);   // atomically
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3986
    // There are null tasks here corresponding to chunks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3987
    // beyond the "top" address of the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3988
    span = span.intersection(sp->used_region());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3989
    if (!span.is_empty()) {  // Non-null task
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3990
      HeapWord* prev_obj;
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3991
      assert(!span.contains(_restart_addr) || nth_task == 0,
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3992
             "Inconsistency");
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3993
      if (nth_task == 0) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3994
        // For the 0th task, we'll not need to compute a block_start.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3995
        if (span.contains(_restart_addr)) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3996
          // In the case of a restart because of stack overflow,
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3997
          // we might additionally skip a chunk prefix.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3998
          prev_obj = _restart_addr;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3999
        } else {
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4000
          prev_obj = span.start();
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4001
        }
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4002
      } else {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4003
        // We want to skip the first object because
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4004
        // the protocol is to scan any object in its entirety
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4005
        // that _starts_ in this span; a fortiori, any
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4006
        // object starting in an earlier span is scanned
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4007
        // as part of an earlier claimed task.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4008
        // Below we use the "careful" version of block_start
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4009
        // so we do not try to navigate uninitialized objects.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4010
        prev_obj = sp->block_start_careful(span.start());
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4011
        // Below we use a variant of block_size that uses the
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4012
        // Printezis bits to avoid waiting for allocated
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4013
        // objects to become initialized/parsable.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4014
        while (prev_obj < span.start()) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4015
          size_t sz = sp->block_size_no_stall(prev_obj, _collector);
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4016
          if (sz > 0) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4017
            prev_obj += sz;
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4018
          } else {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4019
            // In this case we may end up doing a bit of redundant
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4020
            // scanning, but that appears unavoidable, short of
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4021
            // locking the free list locks; see bug 6324141.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4022
            break;
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4023
          }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4024
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4025
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4026
      if (prev_obj < span.end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4027
        MemRegion my_span = MemRegion(prev_obj, span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4028
        // Do the marking work within a non-empty span --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4029
        // the last argument to the constructor indicates whether the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4030
        // iteration should be incremental with periodic yields.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4031
        Par_MarkFromRootsClosure cl(this, _collector, my_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4032
                                    &_collector->_markBitMap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4033
                                    work_queue(i),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4034
                                    &_collector->_markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4035
                                    &_collector->_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4036
                                    _asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4037
        _collector->_markBitMap.iterate(&cl, my_span.start(), my_span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4038
      } // else nothing to do for this task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4039
    }   // else nothing to do for this task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4040
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4041
  // We'd be tempted to assert here that since there are no
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4042
  // more tasks left to claim in this space, the global_finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4043
  // must exceed space->top() and a fortiori space->end(). However,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4044
  // that would not quite be correct because the bumping of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4045
  // global_finger occurs strictly after the claiming of a task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4046
  // so by the time we reach here the global finger may not yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4047
  // have been bumped up by the thread that claimed the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4048
  // task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4049
  pst->all_tasks_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4050
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4051
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4052
class Par_ConcMarkingClosure: public Par_KlassRememberingOopClosure {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4053
 private:
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4054
  CMSConcMarkingTask* _task;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4055
  MemRegion     _span;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4056
  CMSBitMap*    _bit_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4057
  CMSMarkStack* _overflow_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4058
  OopTaskQueue* _work_queue;
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4059
 protected:
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4060
  DO_OOP_WORK_DEFN
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4061
 public:
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4062
  Par_ConcMarkingClosure(CMSCollector* collector, CMSConcMarkingTask* task, OopTaskQueue* work_queue,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4063
                         CMSBitMap* bit_map, CMSMarkStack* overflow_stack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4064
                         CMSMarkStack* revisit_stack):
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4065
    Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4066
    _task(task),
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4067
    _span(collector->_span),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4068
    _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4069
    _bit_map(bit_map),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4070
    _overflow_stack(overflow_stack)
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4071
  { }
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4072
  virtual void do_oop(oop* p);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4073
  virtual void do_oop(narrowOop* p);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4074
  void trim_queue(size_t max);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4075
  void handle_stack_overflow(HeapWord* lost);
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4076
  void do_yield_check() {
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4077
    if (_task->should_yield()) {
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4078
      _task->yield();
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4079
    }
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4080
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4081
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4082
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4083
// Grey object scanning during work stealing phase --
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4084
// the salient assumption here is that any references
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4085
// that are in these stolen objects being scanned must
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4086
// already have been initialized (else they would not have
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4087
// been published), so we do not need to check for
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4088
// uninitialized objects before pushing here.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4089
void Par_ConcMarkingClosure::do_oop(oop obj) {
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4090
  assert(obj->is_oop_or_null(true), "expected an oop or NULL");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4091
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4092
  // Check if oop points into the CMS generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4093
  // and is not marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4094
  if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4095
    // a white object ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4096
    // If we manage to "claim" the object, by being the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4097
    // first thread to mark it, then we push it on our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4098
    // marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4099
    if (_bit_map->par_mark(addr)) {     // ... now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4100
      // push on work queue (grey set)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4101
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4102
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4103
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4104
            _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4105
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4106
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4107
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4108
      )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4109
      if (simulate_overflow ||
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4110
          !(_work_queue->push(obj) || _overflow_stack->par_push(obj))) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4111
        // stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4112
        if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4113
          gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4114
                                 SIZE_FORMAT, _overflow_stack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4115
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4116
        // We cannot assert that the overflow stack is full because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4117
        // it may have been emptied since.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4118
        assert(simulate_overflow ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4119
               _work_queue->size() == _work_queue->max_elems(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4120
              "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4121
        handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4122
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4123
    } // Else, some other thread got there first
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4124
    do_yield_check();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4125
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4126
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4127
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4128
void Par_ConcMarkingClosure::do_oop(oop* p)       { Par_ConcMarkingClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4129
void Par_ConcMarkingClosure::do_oop(narrowOop* p) { Par_ConcMarkingClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4130
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4131
void Par_ConcMarkingClosure::trim_queue(size_t max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4132
  while (_work_queue->size() > max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4133
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4134
    if (_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4135
      assert(new_oop->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4136
      assert(_bit_map->isMarked((HeapWord*)new_oop), "Grey object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4137
      assert(_span.contains((HeapWord*)new_oop), "Not in span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4138
      assert(new_oop->is_parsable(), "Should be parsable");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4139
      new_oop->oop_iterate(this);  // do_oop() above
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4140
      do_yield_check();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4141
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4142
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4143
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4144
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4145
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4146
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4147
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4148
void Par_ConcMarkingClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4149
  // We need to do this under a mutex to prevent other
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4150
  // workers from interfering with the work done below.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4151
  MutexLockerEx ml(_overflow_stack->par_lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4152
                   Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4153
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4154
  HeapWord* ra = (HeapWord*)_overflow_stack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4155
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4156
  _overflow_stack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4157
  _overflow_stack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4158
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4159
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4160
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4161
void CMSConcMarkingTask::do_work_steal(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4162
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4163
  oop obj_to_scan;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4164
  CMSBitMap* bm = &(_collector->_markBitMap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4165
  CMSMarkStack* ovflw = &(_collector->_markStack);
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4166
  CMSMarkStack* revisit = &(_collector->_revisitStack);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4167
  int* seed = _collector->hash_seed(i);
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4168
  Par_ConcMarkingClosure cl(_collector, this, work_q, bm, ovflw, revisit);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4169
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4170
    cl.trim_queue(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4171
    assert(work_q->size() == 0, "Should have been emptied above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4172
    if (get_work_from_overflow_stack(ovflw, work_q)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4173
      // Can't assert below because the work obtained from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4174
      // overflow stack may already have been stolen from us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4175
      // assert(work_q->size() > 0, "Work from overflow stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4176
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4177
    } else if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4178
      assert(obj_to_scan->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4179
      assert(bm->isMarked((HeapWord*)obj_to_scan), "Grey object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4180
      obj_to_scan->oop_iterate(&cl);
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4181
    } else if (terminator()->offer_termination(&_term_term)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4182
      assert(work_q->size() == 0, "Impossible!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4183
      break;
6763
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4184
    } else if (yielding() || should_yield()) {
711b8a44c4dd 6692906: CMS: parallel concurrent marking may be prone to hanging or stalling mutators for periods of time
ysr
parents: 6762
diff changeset
  4185
      yield();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4186
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4187
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4188
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4189
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4190
// This is run by the CMS (coordinator) thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4191
void CMSConcMarkingTask::coordinator_yield() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4192
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4193
         "CMS thread should hold CMS token");
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4194
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4195
  // First give up the locks, then yield, then re-lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4196
  // We should probably use a constructor/destructor idiom to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4197
  // do this unlock/lock or modify the MutexUnlocker class to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4198
  // serve our purpose. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4199
  assert_lock_strong(_bit_map_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4200
  _bit_map_lock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4201
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4202
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4203
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4204
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4205
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4206
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4207
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4208
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4209
  // It is possible for whichever thread initiated the yield request
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4210
  // not to get a chance to wake up and take the bitmap lock between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4211
  // this thread releasing it and reacquiring it. So, while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4212
  // should_yield() flag is on, let's sleep for a bit to give the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4213
  // other thread a chance to wake up. The limit imposed on the number
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4214
  // of iterations is defensive, to avoid any unforseen circumstances
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4215
  // putting us into an infinite loop. Since it's always been this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4216
  // (coordinator_yield()) method that was observed to cause the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4217
  // problem, we are using a parameter (CMSCoordinatorYieldSleepCount)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4218
  // which is by default non-zero. For the other seven methods that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4219
  // also perform the yield operation, as are using a different
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4220
  // parameter (CMSYieldSleepCount) which is by default zero. This way we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4221
  // can enable the sleeping for those methods too, if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4222
  // See 6442774.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4223
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4224
  // We really need to reconsider the synchronization between the GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4225
  // thread and the yield-requesting threads in the future and we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4226
  // should really use wait/notify, which is the recommended
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4227
  // way of doing this type of interaction. Additionally, we should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4228
  // consolidate the eight methods that do the yield operation and they
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4229
  // are almost identical into one for better maintenability and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4230
  // readability. See 6445193.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4231
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4232
  // Tony 2006.06.29
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4233
  for (unsigned i = 0; i < CMSCoordinatorYieldSleepCount &&
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4234
                   ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4235
                   !CMSCollector::foregroundGCIsActive(); ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4236
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4237
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4238
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4239
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4240
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4241
  _bit_map_lock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4242
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4243
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4245
bool CMSCollector::do_marking_mt(bool asynch) {
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
  4246
  assert(ConcGCThreads > 0 && conc_workers() != NULL, "precondition");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4247
  // In the future this would be determined ergonomically, based
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4248
  // on #cpu's, # active mutator threads (and load), and mutation rate.
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
  4249
  int num_workers = ConcGCThreads;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4250
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4251
  CompactibleFreeListSpace* cms_space  = _cmsGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4252
  CompactibleFreeListSpace* perm_space = _permGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4253
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  4254
  CMSConcMarkingTask tsk(this,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  4255
                         cms_space,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  4256
                         perm_space,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  4257
                         asynch,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  4258
                         conc_workers(),
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  4259
                         task_queues());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4260
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4261
  // Since the actual number of workers we get may be different
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4262
  // from the number we requested above, do we need to do anything different
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4263
  // below? In particular, may be we need to subclass the SequantialSubTasksDone
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4264
  // class?? XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4265
  cms_space ->initialize_sequential_subtasks_for_marking(num_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4266
  perm_space->initialize_sequential_subtasks_for_marking(num_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4267
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4268
  // Refs discovery is already non-atomic.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4269
  assert(!ref_processor()->discovery_is_atomic(), "Should be non-atomic");
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  4270
  assert(ref_processor()->discovery_is_mt(), "Discovery should be MT");
4738
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4574
diff changeset
  4271
  DEBUG_ONLY(RememberKlassesChecker cmx(should_unload_classes());)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4272
  conc_workers()->start_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4273
  while (tsk.yielded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4274
    tsk.coordinator_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4275
    conc_workers()->continue_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4276
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4277
  // If the task was aborted, _restart_addr will be non-NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4278
  assert(tsk.completed() || _restart_addr != NULL, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4279
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4280
    // XXX For now we do not make use of ABORTED state and have not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4281
    // yet implemented the right abort semantics (even in the original
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4282
    // single-threaded CMS case). That needs some more investigation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4283
    // and is deferred for now; see CR# TBF. 07252005YSR. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4284
    assert(!CMSAbortSemantics || tsk.aborted(), "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4285
    // If _restart_addr is non-NULL, a marking stack overflow
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1910
diff changeset
  4286
    // occurred; we need to do a fresh marking iteration from the
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4287
    // indicated restart address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4288
    if (_foregroundGCIsActive && asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4289
      // We may be running into repeated stack overflows, having
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4290
      // reached the limit of the stack size, while making very
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4291
      // slow forward progress. It may be best to bail out and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4292
      // let the foreground collector do its job.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4293
      // Clear _restart_addr, so that foreground GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4294
      // works from scratch. This avoids the headache of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4295
      // a "rescan" which would otherwise be needed because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4296
      // of the dirty mod union table & card table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4297
      _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4298
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4299
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4300
    // Adjust the task to restart from _restart_addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4301
    tsk.reset(_restart_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4302
    cms_space ->initialize_sequential_subtasks_for_marking(num_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4303
                  _restart_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4304
    perm_space->initialize_sequential_subtasks_for_marking(num_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4305
                  _restart_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4306
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4307
    // Get the workers going again
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4308
    conc_workers()->start_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4309
    while (tsk.yielded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4310
      tsk.coordinator_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4311
      conc_workers()->continue_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4312
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4313
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4314
  assert(tsk.completed(), "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4315
  assert(tsk.result() == true, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4316
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4317
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4318
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4319
bool CMSCollector::do_marking_st(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4320
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4321
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4322
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  4323
  // Temporarily make refs discovery single threaded (non-MT)
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  4324
  ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4325
  MarkFromRootsClosure markFromRootsClosure(this, _span, &_markBitMap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4326
    &_markStack, &_revisitStack, CMSYield && asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4327
  // the last argument to iterate indicates whether the iteration
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4328
  // should be incremental with periodic yields.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4329
  _markBitMap.iterate(&markFromRootsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4330
  // If _restart_addr is non-NULL, a marking stack overflow
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1910
diff changeset
  4331
  // occurred; we need to do a fresh iteration from the
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4332
  // indicated restart address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4333
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4334
    if (_foregroundGCIsActive && asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4335
      // We may be running into repeated stack overflows, having
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4336
      // reached the limit of the stack size, while making very
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4337
      // slow forward progress. It may be best to bail out and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4338
      // let the foreground collector do its job.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4339
      // Clear _restart_addr, so that foreground GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4340
      // works from scratch. This avoids the headache of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4341
      // a "rescan" which would otherwise be needed because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4342
      // of the dirty mod union table & card table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4343
      _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4344
      return false;  // indicating failure to complete marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4345
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4346
    // Deal with stack overflow:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4347
    // we restart marking from _restart_addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4348
    HeapWord* ra = _restart_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4349
    markFromRootsClosure.reset(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4350
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4351
    _markBitMap.iterate(&markFromRootsClosure, ra, _span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4352
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4353
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4354
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4355
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4356
void CMSCollector::preclean() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4357
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4358
  assert(Thread::current()->is_ConcurrentGC_thread(), "Wrong thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4359
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4360
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4361
  _abort_preclean = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4362
  if (CMSPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4363
    _eden_chunk_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4364
    size_t used = get_eden_used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4365
    size_t capacity = get_eden_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4366
    // Don't start sampling unless we will get sufficiently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4367
    // many samples.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4368
    if (used < (capacity/(CMSScheduleRemarkSamplingRatio * 100)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4369
                * CMSScheduleRemarkEdenPenetration)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4370
      _start_sampling = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4371
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4372
      _start_sampling = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4373
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4374
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4375
    CMSPhaseAccounting pa(this, "preclean", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4376
    preclean_work(CMSPrecleanRefLists1, CMSPrecleanSurvivors1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4377
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4378
  CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4379
  if (CMSPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4380
    sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4381
    _collectorState = AbortablePreclean;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4382
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4383
    _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4384
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4385
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4386
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4387
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4388
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4389
// Try and schedule the remark such that young gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4390
// occupancy is CMSScheduleRemarkEdenPenetration %.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4391
void CMSCollector::abortable_preclean() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4392
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4393
  assert(CMSPrecleaningEnabled,  "Inconsistent control state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4394
  assert(_collectorState == AbortablePreclean, "Inconsistent control state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4395
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4396
  // If Eden's current occupancy is below this threshold,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4397
  // immediately schedule the remark; else preclean
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4398
  // past the next scavenge in an effort to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4399
  // schedule the pause as described avove. By choosing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4400
  // CMSScheduleRemarkEdenSizeThreshold >= max eden size
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4401
  // we will never do an actual abortable preclean cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4402
  if (get_eden_used() > CMSScheduleRemarkEdenSizeThreshold) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4403
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4404
    CMSPhaseAccounting pa(this, "abortable-preclean", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4405
    // We need more smarts in the abortable preclean
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4406
    // loop below to deal with cases where allocation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4407
    // in young gen is very very slow, and our precleaning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4408
    // is running a losing race against a horde of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4409
    // mutators intent on flooding us with CMS updates
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4410
    // (dirty cards).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4411
    // One, admittedly dumb, strategy is to give up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4412
    // after a certain number of abortable precleaning loops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4413
    // or after a certain maximum time. We want to make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4414
    // this smarter in the next iteration.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4415
    // XXX FIX ME!!! YSR
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4416
    size_t loops = 0, workdone = 0, cumworkdone = 0, waited = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4417
    while (!(should_abort_preclean() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4418
             ConcurrentMarkSweepThread::should_terminate())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4419
      workdone = preclean_work(CMSPrecleanRefLists2, CMSPrecleanSurvivors2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4420
      cumworkdone += workdone;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4421
      loops++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4422
      // Voluntarily terminate abortable preclean phase if we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4423
      // been at it for too long.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4424
      if ((CMSMaxAbortablePrecleanLoops != 0) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4425
          loops >= CMSMaxAbortablePrecleanLoops) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4426
        if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4427
          gclog_or_tty->print(" CMS: abort preclean due to loops ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4428
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4429
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4430
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4431
      if (pa.wallclock_millis() > CMSMaxAbortablePrecleanTime) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4432
        if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4433
          gclog_or_tty->print(" CMS: abort preclean due to time ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4434
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4435
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4436
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4437
      // If we are doing little work each iteration, we should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4438
      // take a short break.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4439
      if (workdone < CMSAbortablePrecleanMinWorkPerIteration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4440
        // Sleep for some time, waiting for work to accumulate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4441
        stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4442
        cmsThread()->wait_on_cms_lock(CMSAbortablePrecleanWaitMillis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4443
        startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4444
        waited++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4445
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4446
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4447
    if (PrintCMSStatistics > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4448
      gclog_or_tty->print(" [%d iterations, %d waits, %d cards)] ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4449
                          loops, waited, cumworkdone);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4450
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4451
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4452
  CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4453
  if (_collectorState != Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4454
    assert(_collectorState == AbortablePreclean,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4455
           "Spontaneous state transition?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4456
    _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4457
  } // Else, a foreground collection completed this CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4458
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4459
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4460
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4461
// Respond to an Eden sampling opportunity
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4462
void CMSCollector::sample_eden() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4463
  // Make sure a young gc cannot sneak in between our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4464
  // reading and recording of a sample.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4465
  assert(Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4466
         "Only the cms thread may collect Eden samples");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4467
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4468
         "Should collect samples while holding CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4469
  if (!_start_sampling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4470
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4471
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4472
  if (_eden_chunk_array) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4473
    if (_eden_chunk_index < _eden_chunk_capacity) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4474
      _eden_chunk_array[_eden_chunk_index] = *_top_addr;   // take sample
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4475
      assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4476
             "Unexpected state of Eden");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4477
      // We'd like to check that what we just sampled is an oop-start address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4478
      // however, we cannot do that here since the object may not yet have been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4479
      // initialized. So we'll instead do the check when we _use_ this sample
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4480
      // later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4481
      if (_eden_chunk_index == 0 ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4482
          (pointer_delta(_eden_chunk_array[_eden_chunk_index],
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4483
                         _eden_chunk_array[_eden_chunk_index-1])
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4484
           >= CMSSamplingGrain)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4485
        _eden_chunk_index++;  // commit sample
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4486
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4487
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4488
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4489
  if ((_collectorState == AbortablePreclean) && !_abort_preclean) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4490
    size_t used = get_eden_used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4491
    size_t capacity = get_eden_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4492
    assert(used <= capacity, "Unexpected state of Eden");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4493
    if (used >  (capacity/100 * CMSScheduleRemarkEdenPenetration)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4494
      _abort_preclean = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4495
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4496
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4497
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4498
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4499
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4500
size_t CMSCollector::preclean_work(bool clean_refs, bool clean_survivor) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4501
  assert(_collectorState == Precleaning ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4502
         _collectorState == AbortablePreclean, "incorrect state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4503
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4504
  HandleMark   hm;
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  4505
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  4506
  // Precleaning is currently not MT but the reference processor
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  4507
  // may be set for MT.  Disable it temporarily here.
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  4508
  ReferenceProcessor* rp = ref_processor();
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  4509
  ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(rp, false);
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  4510
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4511
  // Do one pass of scrubbing the discovered reference lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4512
  // to remove any reference objects with strongly-reachable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4513
  // referents.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4514
  if (clean_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4515
    CMSPrecleanRefsYieldClosure yield_cl(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4516
    assert(rp->span().equals(_span), "Spans should be equal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4517
    CMSKeepAliveClosure keep_alive(this, _span, &_markBitMap,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4518
                                   &_markStack, &_revisitStack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4519
                                   true /* preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4520
    CMSDrainMarkingStackClosure complete_trace(this,
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  4521
                                   _span, &_markBitMap, &_markStack,
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  4522
                                   &keep_alive, true /* preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4523
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4524
    // We don't want this step to interfere with a young
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4525
    // collection because we don't want to take CPU
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4526
    // or memory bandwidth away from the young GC threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4527
    // (which may be as many as there are CPUs).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4528
    // Note that we don't need to protect ourselves from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4529
    // interference with mutators because they can't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4530
    // manipulate the discovered reference lists nor affect
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4531
    // the computed reachability of the referents, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4532
    // only properties manipulated by the precleaning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4533
    // of these reference lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4534
    stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4535
    CMSTokenSyncWithLocks x(true /* is cms thread */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4536
                            bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4537
    startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4538
    sample_eden();
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4539
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4540
    // The following will yield to allow foreground
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4541
    // collection to proceed promptly. XXX YSR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4542
    // The code in this method may need further
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4543
    // tweaking for better performance and some restructuring
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4544
    // for cleaner interfaces.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4545
    rp->preclean_discovered_references(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4546
          rp->is_alive_non_header(), &keep_alive, &complete_trace,
4738
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4574
diff changeset
  4547
          &yield_cl, should_unload_classes());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4548
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4549
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4550
  if (clean_survivor) {  // preclean the active survivor space(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4551
    assert(_young_gen->kind() == Generation::DefNew ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4552
           _young_gen->kind() == Generation::ParNew ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4553
           _young_gen->kind() == Generation::ASParNew,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4554
         "incorrect type for cast");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4555
    DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4556
    PushAndMarkClosure pam_cl(this, _span, ref_processor(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4557
                             &_markBitMap, &_modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4558
                             &_markStack, &_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4559
                             true /* precleaning phase */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4560
    stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4561
    CMSTokenSyncWithLocks ts(true /* is cms thread */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4562
                             bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4563
    startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4564
    unsigned int before_count =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4565
      GenCollectedHeap::heap()->total_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4566
    SurvivorSpacePrecleanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4567
      sss_cl(this, _span, &_markBitMap, &_markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4568
             &pam_cl, before_count, CMSYield);
4738
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4574
diff changeset
  4569
    DEBUG_ONLY(RememberKlassesChecker mx(should_unload_classes());)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4570
    dng->from()->object_iterate_careful(&sss_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4571
    dng->to()->object_iterate_careful(&sss_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4572
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4573
  MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4574
    mrias_cl(_span, ref_processor(), &_markBitMap, &_modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4575
             &_markStack, &_revisitStack, this, CMSYield,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4576
             true /* precleaning phase */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4577
  // CAUTION: The following closure has persistent state that may need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4578
  // be reset upon a decrease in the sequence of addresses it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4579
  // processes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4580
  ScanMarkedObjectsAgainCarefullyClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4581
    smoac_cl(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4582
      &_markBitMap, &_markStack, &_revisitStack, &mrias_cl, CMSYield);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4583
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4584
  // Preclean dirty cards in ModUnionTable and CardTable using
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4585
  // appropriate convergence criterion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4586
  // repeat CMSPrecleanIter times unless we find that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4587
  // we are losing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4588
  assert(CMSPrecleanIter < 10, "CMSPrecleanIter is too large");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4589
  assert(CMSPrecleanNumerator < CMSPrecleanDenominator,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4590
         "Bad convergence multiplier");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4591
  assert(CMSPrecleanThreshold >= 100,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4592
         "Unreasonably low CMSPrecleanThreshold");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4593
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4594
  size_t numIter, cumNumCards, lastNumCards, curNumCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4595
  for (numIter = 0, cumNumCards = lastNumCards = curNumCards = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4596
       numIter < CMSPrecleanIter;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4597
       numIter++, lastNumCards = curNumCards, cumNumCards += curNumCards) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4598
    curNumCards  = preclean_mod_union_table(_cmsGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4599
    if (CMSPermGenPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4600
      curNumCards  += preclean_mod_union_table(_permGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4601
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4602
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4603
      gclog_or_tty->print(" (modUnionTable: %d cards)", curNumCards);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4604
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4605
    // Either there are very few dirty cards, so re-mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4606
    // pause will be small anyway, or our pre-cleaning isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4607
    // that much faster than the rate at which cards are being
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4608
    // dirtied, so we might as well stop and re-mark since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4609
    // precleaning won't improve our re-mark time by much.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4610
    if (curNumCards <= CMSPrecleanThreshold ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4611
        (numIter > 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4612
         (curNumCards * CMSPrecleanDenominator >
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4613
         lastNumCards * CMSPrecleanNumerator))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4614
      numIter++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4615
      cumNumCards += curNumCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4616
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4617
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4618
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4619
  curNumCards = preclean_card_table(_cmsGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4620
  if (CMSPermGenPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4621
    curNumCards += preclean_card_table(_permGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4622
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4623
  cumNumCards += curNumCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4624
  if (PrintGCDetails && PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4625
    gclog_or_tty->print_cr(" (cardTable: %d cards, re-scanned %d cards, %d iterations)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4626
                  curNumCards, cumNumCards, numIter);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4627
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4628
  return cumNumCards;   // as a measure of useful work done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4629
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4630
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4631
// PRECLEANING NOTES:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4632
// Precleaning involves:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4633
// . reading the bits of the modUnionTable and clearing the set bits.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4634
// . For the cards corresponding to the set bits, we scan the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4635
//   objects on those cards. This means we need the free_list_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4636
//   so that we can safely iterate over the CMS space when scanning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4637
//   for oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4638
// . When we scan the objects, we'll be both reading and setting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4639
//   marks in the marking bit map, so we'll need the marking bit map.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4640
// . For protecting _collector_state transitions, we take the CGC_lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4641
//   Note that any races in the reading of of card table entries by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4642
//   CMS thread on the one hand and the clearing of those entries by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4643
//   VM thread or the setting of those entries by the mutator threads on the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4644
//   other are quite benign. However, for efficiency it makes sense to keep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4645
//   the VM thread from racing with the CMS thread while the latter is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4646
//   dirty card info to the modUnionTable. We therefore also use the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4647
//   CGC_lock to protect the reading of the card table and the mod union
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4648
//   table by the CM thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4649
// . We run concurrently with mutator updates, so scanning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4650
//   needs to be done carefully  -- we should not try to scan
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4651
//   potentially uninitialized objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4652
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4653
// Locking strategy: While holding the CGC_lock, we scan over and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4654
// reset a maximal dirty range of the mod union / card tables, then lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4655
// the free_list_lock and bitmap lock to do a full marking, then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4656
// release these locks; and repeat the cycle. This allows for a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4657
// certain amount of fairness in the sharing of these locks between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4658
// the CMS collector on the one hand, and the VM thread and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4659
// mutators on the other.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4660
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4661
// NOTE: preclean_mod_union_table() and preclean_card_table()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4662
// further below are largely identical; if you need to modify
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4663
// one of these methods, please check the other method too.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4664
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4665
size_t CMSCollector::preclean_mod_union_table(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4666
  ConcurrentMarkSweepGeneration* gen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4667
  ScanMarkedObjectsAgainCarefullyClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4668
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4669
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4670
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4671
  // Turn off checking for this method but turn it back on
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4672
  // selectively.  There are yield points in this method
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4673
  // but it is difficult to turn the checking off just around
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4674
  // the yield points.  It is simpler to selectively turn
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4675
  // it on.
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4676
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4677
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4678
  // strategy: starting with the first card, accumulate contiguous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4679
  // ranges of dirty cards; clear these cards, then scan the region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4680
  // covered by these cards.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4681
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4682
  // Since all of the MUT is committed ahead, we can just use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4683
  // that, in case the generations expand while we are precleaning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4684
  // It might also be fine to just use the committed part of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4685
  // generation, but we might potentially miss cards when the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4686
  // generation is rapidly expanding while we are in the midst
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4687
  // of precleaning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4688
  HeapWord* startAddr = gen->reserved().start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4689
  HeapWord* endAddr   = gen->reserved().end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4690
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4691
  cl->setFreelistLock(gen->freelistLock());   // needed for yielding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4692
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4693
  size_t numDirtyCards, cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4694
  HeapWord *nextAddr, *lastAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4695
  for (cumNumDirtyCards = numDirtyCards = 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4696
       nextAddr = lastAddr = startAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4697
       nextAddr < endAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4698
       nextAddr = lastAddr, cumNumDirtyCards += numDirtyCards) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4699
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4700
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4701
    HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4702
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4703
    MemRegion dirtyRegion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4704
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4705
      stopTimer();
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4706
      // Potential yield point
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4707
      CMSTokenSync ts(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4708
      startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4709
      sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4710
      // Get dirty region starting at nextOffset (inclusive),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4711
      // simultaneously clearing it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4712
      dirtyRegion =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4713
        _modUnionTable.getAndClearMarkedRegion(nextAddr, endAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4714
      assert(dirtyRegion.start() >= nextAddr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4715
             "returned region inconsistent?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4716
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4717
    // Remember where the next search should begin.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4718
    // The returned region (if non-empty) is a right open interval,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4719
    // so lastOffset is obtained from the right end of that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4720
    // interval.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4721
    lastAddr = dirtyRegion.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4722
    // Should do something more transparent and less hacky XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4723
    numDirtyCards =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4724
      _modUnionTable.heapWordDiffToOffsetDiff(dirtyRegion.word_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4725
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4726
    // We'll scan the cards in the dirty region (with periodic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4727
    // yields for foreground GC as needed).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4728
    if (!dirtyRegion.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4729
      assert(numDirtyCards > 0, "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4730
      HeapWord* stop_point = NULL;
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4731
      stopTimer();
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4732
      // Potential yield point
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4733
      CMSTokenSyncWithLocks ts(true, gen->freelistLock(),
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4734
                               bitMapLock());
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4735
      startTimer();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4736
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4737
        verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4738
        verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4739
        sample_eden();
4738
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4574
diff changeset
  4740
        DEBUG_ONLY(RememberKlassesChecker mx(should_unload_classes());)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4741
        stop_point =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4742
          gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4743
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4744
      if (stop_point != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4745
        // The careful iteration stopped early either because it found an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4746
        // uninitialized object, or because we were in the midst of an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4747
        // "abortable preclean", which should now be aborted. Redirty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4748
        // the bits corresponding to the partially-scanned or unscanned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4749
        // cards. We'll either restart at the next block boundary or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4750
        // abort the preclean.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4751
        assert((CMSPermGenPrecleaningEnabled && (gen == _permGen)) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4752
               (_collectorState == AbortablePreclean && should_abort_preclean()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4753
               "Unparsable objects should only be in perm gen.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4754
        _modUnionTable.mark_range(MemRegion(stop_point, dirtyRegion.end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4755
        if (should_abort_preclean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4756
          break; // out of preclean loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4757
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4758
          // Compute the next address at which preclean should pick up;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4759
          // might need bitMapLock in order to read P-bits.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4760
          lastAddr = next_card_start_after_block(stop_point);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4761
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4762
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4763
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4764
      assert(lastAddr == endAddr, "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4765
      assert(numDirtyCards == 0, "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4766
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4767
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4768
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4769
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4770
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4771
  return cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4772
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4773
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4774
// NOTE: preclean_mod_union_table() above and preclean_card_table()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4775
// below are largely identical; if you need to modify
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4776
// one of these methods, please check the other method too.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4777
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4778
size_t CMSCollector::preclean_card_table(ConcurrentMarkSweepGeneration* gen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4779
  ScanMarkedObjectsAgainCarefullyClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4780
  // strategy: it's similar to precleamModUnionTable above, in that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4781
  // we accumulate contiguous ranges of dirty cards, mark these cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4782
  // precleaned, then scan the region covered by these cards.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4783
  HeapWord* endAddr   = (HeapWord*)(gen->_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4784
  HeapWord* startAddr = (HeapWord*)(gen->_virtual_space.low());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4785
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4786
  cl->setFreelistLock(gen->freelistLock());   // needed for yielding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4787
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4788
  size_t numDirtyCards, cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4789
  HeapWord *lastAddr, *nextAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4790
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4791
  for (cumNumDirtyCards = numDirtyCards = 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4792
       nextAddr = lastAddr = startAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4793
       nextAddr < endAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4794
       nextAddr = lastAddr, cumNumDirtyCards += numDirtyCards) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4795
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4796
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4797
    HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4798
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4799
    MemRegion dirtyRegion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4800
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4801
      // See comments in "Precleaning notes" above on why we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4802
      // do this locking. XXX Could the locking overheads be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4803
      // too high when dirty cards are sparse? [I don't think so.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4804
      stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4805
      CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4806
      startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4807
      sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4808
      // Get and clear dirty region from card table
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4809
      dirtyRegion = _ct->ct_bs()->dirty_card_range_after_reset(
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4810
                                    MemRegion(nextAddr, endAddr),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4811
                                    true,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4812
                                    CardTableModRefBS::precleaned_card_val());
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4813
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4814
      assert(dirtyRegion.start() >= nextAddr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4815
             "returned region inconsistent?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4816
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4817
    lastAddr = dirtyRegion.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4818
    numDirtyCards =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4819
      dirtyRegion.word_size()/CardTableModRefBS::card_size_in_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4820
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4821
    if (!dirtyRegion.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4822
      stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4823
      CMSTokenSyncWithLocks ts(true, gen->freelistLock(), bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4824
      startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4825
      sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4826
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4827
      verify_overflow_empty();
4738
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4574
diff changeset
  4828
      DEBUG_ONLY(RememberKlassesChecker mx(should_unload_classes());)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4829
      HeapWord* stop_point =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4830
        gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4831
      if (stop_point != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4832
        // The careful iteration stopped early because it found an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4833
        // uninitialized object.  Redirty the bits corresponding to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4834
        // partially-scanned or unscanned cards, and start again at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4835
        // next block boundary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4836
        assert(CMSPermGenPrecleaningEnabled ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4837
               (_collectorState == AbortablePreclean && should_abort_preclean()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4838
               "Unparsable objects should only be in perm gen.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4839
        _ct->ct_bs()->invalidate(MemRegion(stop_point, dirtyRegion.end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4840
        if (should_abort_preclean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4841
          break; // out of preclean loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4842
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4843
          // Compute the next address at which preclean should pick up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4844
          lastAddr = next_card_start_after_block(stop_point);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4845
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4846
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4847
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4848
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4849
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4850
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4851
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4852
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4853
  return cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4854
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4855
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4856
void CMSCollector::checkpointRootsFinal(bool asynch,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4857
  bool clear_all_soft_refs, bool init_mark_was_synchronous) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4858
  assert(_collectorState == FinalMarking, "incorrect state transition?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4859
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4860
  // world is stopped at this checkpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4861
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4862
         "world should be stopped");
9623
151c0b638488 7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents: 9342
diff changeset
  4863
  TraceCMSMemoryManagerStats tms(_collectorState,GenCollectedHeap::heap()->gc_cause());
151c0b638488 7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents: 9342
diff changeset
  4864
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4865
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4866
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4867
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4868
  SpecializationStats::clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4869
  if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4870
    gclog_or_tty->print("[YG occupancy: "SIZE_FORMAT" K ("SIZE_FORMAT" K)]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4871
                        _young_gen->used() / K,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4872
                        _young_gen->capacity() / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4873
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4874
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4875
    if (CMSScavengeBeforeRemark) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4876
      GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4877
      // Temporarily set flag to false, GCH->do_collection will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4878
      // expect it to be false and set to true
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4879
      FlagSetting fl(gch->_is_gc_active, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4880
      NOT_PRODUCT(TraceTime t("Scavenge-Before-Remark",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4881
        PrintGCDetails && Verbose, true, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4882
      int level = _cmsGen->level() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4883
      if (level >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4884
        gch->do_collection(true,        // full (i.e. force, see below)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4885
                           false,       // !clear_all_soft_refs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4886
                           0,           // size
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4887
                           false,       // is_tlab
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4888
                           level        // max_level
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4889
                          );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4890
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4891
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4892
    FreelistLocker x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4893
    MutexLockerEx y(bitMapLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4894
                    Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4895
    assert(!init_mark_was_synchronous, "but that's impossible!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4896
    checkpointRootsFinalWork(asynch, clear_all_soft_refs, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4897
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4898
    // already have all the locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4899
    checkpointRootsFinalWork(asynch, clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4900
                             init_mark_was_synchronous);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4901
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4902
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4903
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4904
  SpecializationStats::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4905
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4906
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4907
void CMSCollector::checkpointRootsFinalWork(bool asynch,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4908
  bool clear_all_soft_refs, bool init_mark_was_synchronous) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4909
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4910
  NOT_PRODUCT(TraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4911
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4912
  assert(haveFreelistLocks(), "must have free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4913
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4914
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4915
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4916
    size_policy()->checkpoint_roots_final_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4917
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4918
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4919
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4920
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4921
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4922
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4923
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  4924
  if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4925
    CodeCache::gc_prologue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4926
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4927
  assert(haveFreelistLocks(), "must have free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4928
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4929
4738
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4574
diff changeset
  4930
  DEBUG_ONLY(RememberKlassesChecker fmx(should_unload_classes());)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4931
  if (!init_mark_was_synchronous) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4932
    // We might assume that we need not fill TLAB's when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4933
    // CMSScavengeBeforeRemark is set, because we may have just done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4934
    // a scavenge which would have filled all TLAB's -- and besides
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4935
    // Eden would be empty. This however may not always be the case --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4936
    // for instance although we asked for a scavenge, it may not have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4937
    // happened because of a JNI critical section. We probably need
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4938
    // a policy for deciding whether we can in that case wait until
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4939
    // the critical section releases and then do the remark following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4940
    // the scavenge, and skip it here. In the absence of that policy,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4941
    // or of an indication of whether the scavenge did indeed occur,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4942
    // we cannot rely on TLAB's having been filled and must do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4943
    // so here just in case a scavenge did not happen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4944
    gch->ensure_parsability(false);  // fill TLAB's, but no need to retire them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4945
    // Update the saved marks which may affect the root scans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4946
    gch->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4947
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4948
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4949
      COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4950
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4951
      // Note on the role of the mod union table:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4952
      // Since the marker in "markFromRoots" marks concurrently with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4953
      // mutators, it is possible for some reachable objects not to have been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4954
      // scanned. For instance, an only reference to an object A was
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4955
      // placed in object B after the marker scanned B. Unless B is rescanned,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4956
      // A would be collected. Such updates to references in marked objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4957
      // are detected via the mod union table which is the set of all cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4958
      // dirtied since the first checkpoint in this GC cycle and prior to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4959
      // the most recent young generation GC, minus those cleaned up by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4960
      // concurrent precleaning.
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  4961
      if (CMSParallelRemarkEnabled && CollectedHeap::use_parallel_gc_threads()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4962
        TraceTime t("Rescan (parallel) ", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4963
        do_remark_parallel();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4964
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4965
        TraceTime t("Rescan (non-parallel) ", PrintGCDetails, false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4966
                    gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4967
        do_remark_non_parallel();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4968
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4969
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4970
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4971
    assert(!asynch, "Can't have init_mark_was_synchronous in asynch mode");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4972
    // The initial mark was stop-world, so there's no rescanning to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4973
    // do; go straight on to the next step below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4974
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4975
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4976
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4977
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4978
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4979
    NOT_PRODUCT(TraceTime ts("refProcessingWork", PrintGCDetails, false, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4980
    refProcessingWork(asynch, clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4981
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4982
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4983
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4984
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  4985
  if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4986
    CodeCache::gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4987
  }
7918
ce1e4ae77aea 7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents: 7908
diff changeset
  4988
  JvmtiExport::gc_epilogue();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4989
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4990
  // If we encountered any (marking stack / work queue) overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4991
  // events during the current CMS cycle, take appropriate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4992
  // remedial measures, where possible, so as to try and avoid
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4993
  // recurrence of that condition.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4994
  assert(_markStack.isEmpty(), "No grey objects");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4995
  size_t ser_ovflw = _ser_pmc_remark_ovflw + _ser_pmc_preclean_ovflw +
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  4996
                     _ser_kac_ovflw        + _ser_kac_preclean_ovflw;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4997
  if (ser_ovflw > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4998
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4999
      gclog_or_tty->print_cr("Marking stack overflow (benign) "
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  5000
        "(pmc_pc="SIZE_FORMAT", pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  5001
        ", kac_preclean="SIZE_FORMAT")",
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5002
        _ser_pmc_preclean_ovflw, _ser_pmc_remark_ovflw,
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  5003
        _ser_kac_ovflw, _ser_kac_preclean_ovflw);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5004
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5005
    _markStack.expand();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5006
    _ser_pmc_remark_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5007
    _ser_pmc_preclean_ovflw = 0;
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  5008
    _ser_kac_preclean_ovflw = 0;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5009
    _ser_kac_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5010
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5011
  if (_par_pmc_remark_ovflw > 0 || _par_kac_ovflw > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5012
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5013
      gclog_or_tty->print_cr("Work queue overflow (benign) "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5014
        "(pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT")",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5015
        _par_pmc_remark_ovflw, _par_kac_ovflw);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5016
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5017
    _par_pmc_remark_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5018
    _par_kac_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5019
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5020
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5021
     if (_markStack._hit_limit > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5022
       gclog_or_tty->print_cr(" (benign) Hit max stack size limit ("SIZE_FORMAT")",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5023
                              _markStack._hit_limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5024
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5025
     if (_markStack._failed_double > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5026
       gclog_or_tty->print_cr(" (benign) Failed stack doubling ("SIZE_FORMAT"),"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5027
                              " current capacity "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5028
                              _markStack._failed_double,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5029
                              _markStack.capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5030
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5031
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5032
  _markStack._hit_limit = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5033
  _markStack._failed_double = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5034
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5035
  // Check that all the klasses have been checked
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5036
  assert(_revisitStack.isEmpty(), "Not all klasses revisited");
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5037
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5038
  if ((VerifyAfterGC || VerifyDuringGC) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5039
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5040
    verify_after_remark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5041
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5042
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5043
  // Change under the freelistLocks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5044
  _collectorState = Sweeping;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5045
  // Call isAllClear() under bitMapLock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5046
  assert(_modUnionTable.isAllClear(), "Should be clear by end of the"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5047
    " final marking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5048
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5049
    size_policy()->checkpoint_roots_final_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5050
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5051
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5052
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5053
// Parallel remark task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5054
class CMSParRemarkTask: public AbstractGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5055
  CMSCollector* _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5056
  int           _n_workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5057
  CompactibleFreeListSpace* _cms_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5058
  CompactibleFreeListSpace* _perm_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5059
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5060
  // The per-thread work queues, available here for stealing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5061
  OopTaskQueueSet*       _task_queues;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5062
  ParallelTaskTerminator _term;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5063
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5064
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5065
  CMSParRemarkTask(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5066
                   CompactibleFreeListSpace* cms_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5067
                   CompactibleFreeListSpace* perm_space,
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5068
                   int n_workers, FlexibleWorkGang* workers,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5069
                   OopTaskQueueSet* task_queues):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5070
    AbstractGangTask("Rescan roots and grey objects in parallel"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5071
    _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5072
    _cms_space(cms_space), _perm_space(perm_space),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5073
    _n_workers(n_workers),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5074
    _task_queues(task_queues),
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5075
    _term(n_workers, task_queues) { }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5076
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5077
  OopTaskQueueSet* task_queues() { return _task_queues; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5078
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5079
  OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5080
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5081
  ParallelTaskTerminator* terminator() { return &_term; }
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5082
  int n_workers() { return _n_workers; }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5083
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5084
  void work(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5085
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5086
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5087
  // Work method in support of parallel rescan ... of young gen spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5088
  void do_young_space_rescan(int i, Par_MarkRefsIntoAndScanClosure* cl,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5089
                             ContiguousSpace* space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5090
                             HeapWord** chunk_array, size_t chunk_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5091
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5092
  // ... of  dirty cards in old space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5093
  void do_dirty_card_rescan_tasks(CompactibleFreeListSpace* sp, int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5094
                                  Par_MarkRefsIntoAndScanClosure* cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5095
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5096
  // ... work stealing for the above
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5097
  void do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl, int* seed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5098
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5099
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5100
// work_queue(i) is passed to the closure
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5101
// Par_MarkRefsIntoAndScanClosure.  The "i" parameter
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5102
// also is passed to do_dirty_card_rescan_tasks() and to
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5103
// do_work_steal() to select the i-th task_queue.
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5104
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5105
void CMSParRemarkTask::work(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5106
  elapsedTimer _timer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5107
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5108
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5109
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5110
  // ---------- rescan from roots --------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5111
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5112
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5113
  Par_MarkRefsIntoAndScanClosure par_mrias_cl(_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5114
    _collector->_span, _collector->ref_processor(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5115
    &(_collector->_markBitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5116
    work_queue(i), &(_collector->_revisitStack));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5117
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5118
  // Rescan young gen roots first since these are likely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5119
  // coarsely partitioned and may, on that account, constitute
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5120
  // the critical path; thus, it's best to start off that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5121
  // work first.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5122
  // ---------- young gen roots --------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5123
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5124
    DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5125
    EdenSpace* eden_space = dng->eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5126
    ContiguousSpace* from_space = dng->from();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5127
    ContiguousSpace* to_space   = dng->to();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5128
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5129
    HeapWord** eca = _collector->_eden_chunk_array;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5130
    size_t     ect = _collector->_eden_chunk_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5131
    HeapWord** sca = _collector->_survivor_chunk_array;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5132
    size_t     sct = _collector->_survivor_chunk_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5133
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5134
    assert(ect <= _collector->_eden_chunk_capacity, "out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5135
    assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5136
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5137
    do_young_space_rescan(i, &par_mrias_cl, to_space, NULL, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5138
    do_young_space_rescan(i, &par_mrias_cl, from_space, sca, sct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5139
    do_young_space_rescan(i, &par_mrias_cl, eden_space, eca, ect);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5140
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5141
    _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5142
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5143
      gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5144
        "Finished young gen rescan work in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5145
        i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5146
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5147
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5148
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5149
  // ---------- remaining roots --------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5150
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5151
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5152
  gch->gen_process_strong_roots(_collector->_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5153
                                false,     // yg was scanned above
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5154
                                false,     // this is parallel code
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5155
                                true,      // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5156
                                SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5157
                                &par_mrias_cl,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5158
                                true,   // walk all of code cache if (so & SO_CodeCache)
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5159
                                NULL);
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5160
  assert(_collector->should_unload_classes()
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5161
         || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_CodeCache),
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5162
         "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5163
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5164
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5165
    gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5166
      "Finished remaining root rescan work in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5167
      i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5168
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5169
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5170
  // ---------- rescan dirty cards ------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5171
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5172
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5173
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5174
  // Do the rescan tasks for each of the two spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5175
  // (cms_space and perm_space) in turn.
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5176
  // "i" is passed to select the "i-th" task_queue
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5177
  do_dirty_card_rescan_tasks(_cms_space, i, &par_mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5178
  do_dirty_card_rescan_tasks(_perm_space, i, &par_mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5179
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5180
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5181
    gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5182
      "Finished dirty card rescan work in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5183
      i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5184
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5185
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5186
  // ---------- steal work from other threads ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5187
  // ---------- ... and drain overflow list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5188
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5189
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5190
  do_work_steal(i, &par_mrias_cl, _collector->hash_seed(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5191
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5192
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5193
    gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5194
      "Finished work stealing in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5195
      i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5196
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5197
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5198
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5199
// Note that parameter "i" is not used.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5200
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5201
CMSParRemarkTask::do_young_space_rescan(int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5202
  Par_MarkRefsIntoAndScanClosure* cl, ContiguousSpace* space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5203
  HeapWord** chunk_array, size_t chunk_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5204
  // Until all tasks completed:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5205
  // . claim an unclaimed task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5206
  // . compute region boundaries corresponding to task claimed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5207
  //   using chunk_array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5208
  // . par_oop_iterate(cl) over that region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5209
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5210
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5211
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5212
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5213
  SequentialSubTasksDone* pst = space->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5214
  assert(pst->valid(), "Uninitialized use?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5215
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5216
  int nth_task = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5217
  int n_tasks  = pst->n_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5218
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5219
  HeapWord *start, *end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5220
  while (!pst->is_task_claimed(/* reference */ nth_task)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5221
    // We claimed task # nth_task; compute its boundaries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5222
    if (chunk_top == 0) {  // no samples were taken
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5223
      assert(nth_task == 0 && n_tasks == 1, "Can have only 1 EdenSpace task");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5224
      start = space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5225
      end   = space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5226
    } else if (nth_task == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5227
      start = space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5228
      end   = chunk_array[nth_task];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5229
    } else if (nth_task < (jint)chunk_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5230
      assert(nth_task >= 1, "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5231
      start = chunk_array[nth_task - 1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5232
      end   = chunk_array[nth_task];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5233
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5234
      assert(nth_task == (jint)chunk_top, "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5235
      start = chunk_array[chunk_top - 1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5236
      end   = space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5237
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5238
    MemRegion mr(start, end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5239
    // Verify that mr is in space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5240
    assert(mr.is_empty() || space->used_region().contains(mr),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5241
           "Should be in space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5242
    // Verify that "start" is an object boundary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5243
    assert(mr.is_empty() || oop(mr.start())->is_oop(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5244
           "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5245
    space->par_oop_iterate(mr, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5246
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5247
  pst->all_tasks_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5248
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5249
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5250
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5251
CMSParRemarkTask::do_dirty_card_rescan_tasks(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5252
  CompactibleFreeListSpace* sp, int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5253
  Par_MarkRefsIntoAndScanClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5254
  // Until all tasks completed:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5255
  // . claim an unclaimed task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5256
  // . compute region boundaries corresponding to task claimed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5257
  // . transfer dirty bits ct->mut for that region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5258
  // . apply rescanclosure to dirty mut bits for that region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5259
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5260
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5261
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5262
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5263
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5264
  ModUnionClosure modUnionClosure(&(_collector->_modUnionTable));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5265
  // CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! CAUTION!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5266
  // CAUTION: This closure has state that persists across calls to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5267
  // the work method dirty_range_iterate_clear() in that it has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5268
  // imbedded in it a (subtype of) UpwardsObjectClosure. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5269
  // use of that state in the imbedded UpwardsObjectClosure instance
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5270
  // assumes that the cards are always iterated (even if in parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5271
  // by several threads) in monotonically increasing order per each
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5272
  // thread. This is true of the implementation below which picks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5273
  // card ranges (chunks) in monotonically increasing order globally
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5274
  // and, a-fortiori, in monotonically increasing order per thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5275
  // (the latter order being a subsequence of the former).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5276
  // If the work code below is ever reorganized into a more chaotic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5277
  // work-partitioning form than the current "sequential tasks"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5278
  // paradigm, the use of that persistent state will have to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5279
  // revisited and modified appropriately. See also related
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5280
  // bug 4756801 work on which should examine this code to make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5281
  // sure that the changes there do not run counter to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5282
  // assumptions made here and necessary for correctness and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5283
  // efficiency. Note also that this code might yield inefficient
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5284
  // behaviour in the case of very large objects that span one or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5285
  // more work chunks. Such objects would potentially be scanned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5286
  // several times redundantly. Work on 4756801 should try and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5287
  // address that performance anomaly if at all possible. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5288
  MemRegion  full_span  = _collector->_span;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5289
  CMSBitMap* bm    = &(_collector->_markBitMap);     // shared
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5290
  CMSMarkStack* rs = &(_collector->_revisitStack);   // shared
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5291
  MarkFromDirtyCardsClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5292
    greyRescanClosure(_collector, full_span, // entire span of interest
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5293
                      sp, bm, work_q, rs, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5295
  SequentialSubTasksDone* pst = sp->conc_par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5296
  assert(pst->valid(), "Uninitialized use?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5297
  int nth_task = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5298
  const int alignment = CardTableModRefBS::card_size * BitsPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5299
  MemRegion span = sp->used_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5300
  HeapWord* start_addr = span.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5301
  HeapWord* end_addr = (HeapWord*)round_to((intptr_t)span.end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5302
                                           alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5303
  const size_t chunk_size = sp->rescan_task_size(); // in HeapWord units
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5304
  assert((HeapWord*)round_to((intptr_t)start_addr, alignment) ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5305
         start_addr, "Check alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5306
  assert((size_t)round_to((intptr_t)chunk_size, alignment) ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5307
         chunk_size, "Check alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5308
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5309
  while (!pst->is_task_claimed(/* reference */ nth_task)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5310
    // Having claimed the nth_task, compute corresponding mem-region,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5311
    // which is a-fortiori aligned correctly (i.e. at a MUT bopundary).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5312
    // The alignment restriction ensures that we do not need any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5313
    // synchronization with other gang-workers while setting or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5314
    // clearing bits in thus chunk of the MUT.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5315
    MemRegion this_span = MemRegion(start_addr + nth_task*chunk_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5316
                                    start_addr + (nth_task+1)*chunk_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5317
    // The last chunk's end might be way beyond end of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5318
    // used region. In that case pull back appropriately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5319
    if (this_span.end() > end_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5320
      this_span.set_end(end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5321
      assert(!this_span.is_empty(), "Program logic (calculation of n_tasks)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5322
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5323
    // Iterate over the dirty cards covering this chunk, marking them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5324
    // precleaned, and setting the corresponding bits in the mod union
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5325
    // table. Since we have been careful to partition at Card and MUT-word
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5326
    // boundaries no synchronization is needed between parallel threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5327
    _collector->_ct->ct_bs()->dirty_card_iterate(this_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5328
                                                 &modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5329
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5330
    // Having transferred these marks into the modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5331
    // rescan the marked objects on the dirty cards in the modUnionTable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5332
    // Even if this is at a synchronous collection, the initial marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5333
    // may have been done during an asynchronous collection so there
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5334
    // may be dirty bits in the mod-union table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5335
    _collector->_modUnionTable.dirty_range_iterate_clear(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5336
                  this_span, &greyRescanClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5337
    _collector->_modUnionTable.verifyNoOneBitsInRange(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5338
                                 this_span.start(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5339
                                 this_span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5340
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5341
  pst->all_tasks_completed();  // declare that i am done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5342
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5343
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5344
// . see if we can share work_queues with ParNew? XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5345
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5346
CMSParRemarkTask::do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5347
                                int* seed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5348
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5349
  NOT_PRODUCT(int num_steals = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5350
  oop obj_to_scan;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5351
  CMSBitMap* bm = &(_collector->_markBitMap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5352
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5353
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5354
    // Completely finish any left over work from (an) earlier round(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5355
    cl->trim_queue(0);
2346
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  5356
    size_t num_from_overflow_list = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  5357
                                         (size_t)ParGCDesiredObjsFromOverflowList);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5358
    // Now check if there's any work in the overflow list
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5359
    // Passing ParallelGCThreads as the third parameter, no_of_gc_threads,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5360
    // only affects the number of attempts made to get work from the
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5361
    // overflow list and does not affect the number of workers.  Just
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5362
    // pass ParallelGCThreads so this behavior is unchanged.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5363
    if (_collector->par_take_from_overflow_list(num_from_overflow_list,
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5364
                                                work_q,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5365
                                                ParallelGCThreads)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5366
      // found something in global overflow list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5367
      // not yet ready to go stealing work from others.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5368
      // We'd like to assert(work_q->size() != 0, ...)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5369
      // because we just took work from the overflow list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5370
      // but of course we can't since all of that could have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5371
      // been already stolen from us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5372
      // "He giveth and He taketh away."
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5373
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5374
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5375
    // Verify that we have no work before we resort to stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5376
    assert(work_q->size() == 0, "Have work, shouldn't steal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5377
    // Try to steal from other queues that have work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5378
    if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5379
      NOT_PRODUCT(num_steals++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5380
      assert(obj_to_scan->is_oop(), "Oops, not an oop!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5381
      assert(bm->isMarked((HeapWord*)obj_to_scan), "Stole an unmarked oop?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5382
      // Do scanning work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5383
      obj_to_scan->oop_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5384
      // Loop around, finish this work, and try to steal some more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5385
    } else if (terminator()->offer_termination()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5386
        break;  // nirvana from the infinite cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5387
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5388
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5389
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5390
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5391
      gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5392
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5393
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5394
  assert(work_q->size() == 0 && _collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5395
         "Else our work is not yet done");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5396
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5397
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5398
// Return a thread-local PLAB recording array, as appropriate.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5399
void* CMSCollector::get_data_recorder(int thr_num) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5400
  if (_survivor_plab_array != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5401
      (CMSPLABRecordAlways ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5402
       (_collectorState > Marking && _collectorState < FinalMarking))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5403
    assert(thr_num < (int)ParallelGCThreads, "thr_num is out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5404
    ChunkArray* ca = &_survivor_plab_array[thr_num];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5405
    ca->reset();   // clear it so that fresh data is recorded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5406
    return (void*) ca;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5407
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5408
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5409
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5410
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5411
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5412
// Reset all the thread-local PLAB recording arrays
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5413
void CMSCollector::reset_survivor_plab_arrays() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5414
  for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5415
    _survivor_plab_array[i].reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5416
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5417
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5418
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5419
// Merge the per-thread plab arrays into the global survivor chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5420
// array which will provide the partitioning of the survivor space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5421
// for CMS rescan.
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5422
void CMSCollector::merge_survivor_plab_arrays(ContiguousSpace* surv,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5423
                                              int no_of_gc_threads) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5424
  assert(_survivor_plab_array  != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5425
  assert(_survivor_chunk_array != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5426
  assert(_collectorState == FinalMarking, "Error");
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5427
  for (int j = 0; j < no_of_gc_threads; j++) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5428
    _cursor[j] = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5429
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5430
  HeapWord* top = surv->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5431
  size_t i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5432
  for (i = 0; i < _survivor_chunk_capacity; i++) {  // all sca entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5433
    HeapWord* min_val = top;          // Higher than any PLAB address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5434
    uint      min_tid = 0;            // position of min_val this round
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5435
    for (int j = 0; j < no_of_gc_threads; j++) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5436
      ChunkArray* cur_sca = &_survivor_plab_array[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5437
      if (_cursor[j] == cur_sca->end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5438
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5439
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5440
      assert(_cursor[j] < cur_sca->end(), "ctl pt invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5441
      HeapWord* cur_val = cur_sca->nth(_cursor[j]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5442
      assert(surv->used_region().contains(cur_val), "Out of bounds value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5443
      if (cur_val < min_val) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5444
        min_tid = j;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5445
        min_val = cur_val;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5446
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5447
        assert(cur_val < top, "All recorded addresses should be less");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5448
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5449
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5450
    // At this point min_val and min_tid are respectively
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5451
    // the least address in _survivor_plab_array[j]->nth(_cursor[j])
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5452
    // and the thread (j) that witnesses that address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5453
    // We record this address in the _survivor_chunk_array[i]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5454
    // and increment _cursor[min_tid] prior to the next round i.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5455
    if (min_val == top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5456
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5457
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5458
    _survivor_chunk_array[i] = min_val;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5459
    _cursor[min_tid]++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5460
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5461
  // We are all done; record the size of the _survivor_chunk_array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5462
  _survivor_chunk_index = i; // exclusive: [0, i)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5463
  if (PrintCMSStatistics > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5464
    gclog_or_tty->print(" (Survivor:" SIZE_FORMAT "chunks) ", i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5465
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5466
  // Verify that we used up all the recorded entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5467
  #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5468
    size_t total = 0;
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5469
    for (int j = 0; j < no_of_gc_threads; j++) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5470
      assert(_cursor[j] == _survivor_plab_array[j].end(), "Ctl pt invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5471
      total += _cursor[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5472
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5473
    assert(total == _survivor_chunk_index, "Ctl Pt Invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5474
    // Check that the merged array is in sorted order
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5475
    if (total > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5476
      for (size_t i = 0; i < total - 1; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5477
        if (PrintCMSStatistics > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5478
          gclog_or_tty->print(" (chunk" SIZE_FORMAT ":" INTPTR_FORMAT ") ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5479
                              i, _survivor_chunk_array[i]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5480
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5481
        assert(_survivor_chunk_array[i] < _survivor_chunk_array[i+1],
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5482
               "Not sorted");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5483
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5484
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5485
  #endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5486
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5487
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5488
// Set up the space's par_seq_tasks structure for work claiming
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5489
// for parallel rescan of young gen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5490
// See ParRescanTask where this is currently used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5491
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5492
CMSCollector::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5493
initialize_sequential_subtasks_for_young_gen_rescan(int n_threads) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5494
  assert(n_threads > 0, "Unexpected n_threads argument");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5495
  DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5496
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5497
  // Eden space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5498
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5499
    SequentialSubTasksDone* pst = dng->eden()->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5500
    assert(!pst->valid(), "Clobbering existing data?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5501
    // Each valid entry in [0, _eden_chunk_index) represents a task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5502
    size_t n_tasks = _eden_chunk_index + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5503
    assert(n_tasks == 1 || _eden_chunk_array != NULL, "Error");
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5504
    // Sets the condition for completion of the subtask (how many threads
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5505
    // need to finish in order to be done).
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5506
    pst->set_n_threads(n_threads);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5507
    pst->set_n_tasks((int)n_tasks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5508
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5509
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5510
  // Merge the survivor plab arrays into _survivor_chunk_array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5511
  if (_survivor_plab_array != NULL) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5512
    merge_survivor_plab_arrays(dng->from(), n_threads);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5513
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5514
    assert(_survivor_chunk_index == 0, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5515
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5516
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5517
  // To space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5518
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5519
    SequentialSubTasksDone* pst = dng->to()->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5520
    assert(!pst->valid(), "Clobbering existing data?");
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5521
    // Sets the condition for completion of the subtask (how many threads
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5522
    // need to finish in order to be done).
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5523
    pst->set_n_threads(n_threads);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5524
    pst->set_n_tasks(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5525
    assert(pst->valid(), "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5526
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5527
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5528
  // From space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5529
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5530
    SequentialSubTasksDone* pst = dng->from()->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5531
    assert(!pst->valid(), "Clobbering existing data?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5532
    size_t n_tasks = _survivor_chunk_index + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5533
    assert(n_tasks == 1 || _survivor_chunk_array != NULL, "Error");
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5534
    // Sets the condition for completion of the subtask (how many threads
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5535
    // need to finish in order to be done).
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5536
    pst->set_n_threads(n_threads);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5537
    pst->set_n_tasks((int)n_tasks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5538
    assert(pst->valid(), "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5539
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5540
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5541
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5542
// Parallel version of remark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5543
void CMSCollector::do_remark_parallel() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5544
  GenCollectedHeap* gch = GenCollectedHeap::heap();
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5545
  FlexibleWorkGang* workers = gch->workers();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5546
  assert(workers != NULL, "Need parallel worker threads.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5547
  int n_workers = workers->total_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5548
  CompactibleFreeListSpace* cms_space  = _cmsGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5549
  CompactibleFreeListSpace* perm_space = _permGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5550
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5551
  CMSParRemarkTask tsk(this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5552
    cms_space, perm_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5553
    n_workers, workers, task_queues());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5554
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5555
  // Set up for parallel process_strong_roots work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5556
  gch->set_par_threads(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5557
  // We won't be iterating over the cards in the card table updating
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5558
  // the younger_gen cards, so we shouldn't call the following else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5559
  // the verification code as well as subsequent younger_refs_iterate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5560
  // code would get confused. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5561
  // gch->rem_set()->prepare_for_younger_refs_iterate(true); // parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5562
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5563
  // The young gen rescan work will not be done as part of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5564
  // process_strong_roots (which currently doesn't knw how to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5565
  // parallelize such a scan), but rather will be broken up into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5566
  // a set of parallel tasks (via the sampling that the [abortable]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5567
  // preclean phase did of EdenSpace, plus the [two] tasks of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5568
  // scanning the [two] survivor spaces. Further fine-grain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5569
  // parallelization of the scanning of the survivor spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5570
  // themselves, and of precleaning of the younger gen itself
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5571
  // is deferred to the future.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5572
  initialize_sequential_subtasks_for_young_gen_rescan(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5573
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5574
  // The dirty card rescan work is broken up into a "sequence"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5575
  // of parallel tasks (per constituent space) that are dynamically
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5576
  // claimed by the parallel threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5577
  cms_space->initialize_sequential_subtasks_for_rescan(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5578
  perm_space->initialize_sequential_subtasks_for_rescan(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5579
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5580
  // It turns out that even when we're using 1 thread, doing the work in a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5581
  // separate thread causes wide variance in run times.  We can't help this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5582
  // in the multi-threaded case, but we special-case n=1 here to get
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5583
  // repeatable measurements of the 1-thread overhead of the parallel code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5584
  if (n_workers > 1) {
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5585
    // Make refs discovery MT-safe, if it isn't already: it may not
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5586
    // necessarily be so, since it's possible that we are doing
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5587
    // ST marking.
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5588
    ReferenceProcessorMTDiscoveryMutator mt(ref_processor(), true);
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5589
    GenCollectedHeap::StrongRootsScope srs(gch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5590
    workers->run_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5591
  } else {
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5592
    GenCollectedHeap::StrongRootsScope srs(gch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5593
    tsk.work(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5594
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5595
  gch->set_par_threads(0);  // 0 ==> non-parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5596
  // restore, single-threaded for now, any preserved marks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5597
  // as a result of work_q overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5598
  restore_preserved_marks_if_any();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5599
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5600
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5601
// Non-parallel version of remark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5602
void CMSCollector::do_remark_non_parallel() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5603
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5604
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5605
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5606
  MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5607
    mrias_cl(_span, ref_processor(), &_markBitMap, &_modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5608
             &_markStack, &_revisitStack, this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5609
             false /* should_yield */, false /* not precleaning */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5610
  MarkFromDirtyCardsClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5611
    markFromDirtyCardsClosure(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5612
                              NULL,  // space is set further below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5613
                              &_markBitMap, &_markStack, &_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5614
                              &mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5615
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5616
    TraceTime t("grey object rescan", PrintGCDetails, false, gclog_or_tty);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  5617
    // Iterate over the dirty cards, setting the corresponding bits in the
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  5618
    // mod union table.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5619
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5620
      ModUnionClosure modUnionClosure(&_modUnionTable);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5621
      _ct->ct_bs()->dirty_card_iterate(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5622
                      _cmsGen->used_region(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5623
                      &modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5624
      _ct->ct_bs()->dirty_card_iterate(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5625
                      _permGen->used_region(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5626
                      &modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5627
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5628
    // Having transferred these marks into the modUnionTable, we just need
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5629
    // to rescan the marked objects on the dirty cards in the modUnionTable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5630
    // The initial marking may have been done during an asynchronous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5631
    // collection so there may be dirty bits in the mod-union table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5632
    const int alignment =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5633
      CardTableModRefBS::card_size * BitsPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5634
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5635
      // ... First handle dirty cards in CMS gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5636
      markFromDirtyCardsClosure.set_space(_cmsGen->cmsSpace());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5637
      MemRegion ur = _cmsGen->used_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5638
      HeapWord* lb = ur.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5639
      HeapWord* ub = (HeapWord*)round_to((intptr_t)ur.end(), alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5640
      MemRegion cms_span(lb, ub);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5641
      _modUnionTable.dirty_range_iterate_clear(cms_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5642
                                               &markFromDirtyCardsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5643
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5644
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5645
        gclog_or_tty->print(" (re-scanned "SIZE_FORMAT" dirty cards in cms gen) ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5646
          markFromDirtyCardsClosure.num_dirty_cards());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5647
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5648
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5649
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5650
      // .. and then repeat for dirty cards in perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5651
      markFromDirtyCardsClosure.set_space(_permGen->cmsSpace());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5652
      MemRegion ur = _permGen->used_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5653
      HeapWord* lb = ur.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5654
      HeapWord* ub = (HeapWord*)round_to((intptr_t)ur.end(), alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5655
      MemRegion perm_span(lb, ub);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5656
      _modUnionTable.dirty_range_iterate_clear(perm_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5657
                                               &markFromDirtyCardsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5658
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5659
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5660
        gclog_or_tty->print(" (re-scanned "SIZE_FORMAT" dirty cards in perm gen) ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5661
          markFromDirtyCardsClosure.num_dirty_cards());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5662
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5663
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5664
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5665
  if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5666
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5667
    HandleMark hm;  // Discard invalid handles created during verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5668
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5669
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5670
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5671
    TraceTime t("root rescan", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5672
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5673
    verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5674
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5675
    gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5676
    GenCollectedHeap::StrongRootsScope srs(gch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5677
    gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5678
                                  true,  // younger gens as roots
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5679
                                  false, // use the local StrongRootsScope
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5680
                                  true,  // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5681
                                  SharedHeap::ScanningOption(roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5682
                                  &mrias_cl,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5683
                                  true,   // walk code active on stacks
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5684
                                  NULL);
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5685
    assert(should_unload_classes()
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5686
           || (roots_scanning_options() & SharedHeap::SO_CodeCache),
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5687
           "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5688
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5689
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5690
  // Restore evacuated mark words, if any, used for overflow list links
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5691
  if (!CMSOverflowEarlyRestoration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5692
    restore_preserved_marks_if_any();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5693
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5694
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5695
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5696
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5697
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5698
// Parallel Reference Processing Task Proxy Class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5699
////////////////////////////////////////////////////////
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5700
class CMSRefProcTaskProxy: public AbstractGangTaskWOopQueues {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5701
  typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5702
  CMSCollector*          _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5703
  CMSBitMap*             _mark_bit_map;
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5704
  const MemRegion        _span;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5705
  ProcessTask&           _task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5706
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5707
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5708
  CMSRefProcTaskProxy(ProcessTask&     task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5709
                      CMSCollector*    collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5710
                      const MemRegion& span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5711
                      CMSBitMap*       mark_bit_map,
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5712
                      AbstractWorkGang* workers,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5713
                      OopTaskQueueSet* task_queues):
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5714
    // XXX Should superclass AGTWOQ also know about AWG since it knows
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5715
    // about the task_queues used by the AWG? Then it could initialize
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5716
    // the terminator() object. See 6984287. The set_for_termination()
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5717
    // below is a temporary band-aid for the regression in 6984287.
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5718
    AbstractGangTaskWOopQueues("Process referents by policy in parallel",
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5719
      task_queues),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5720
    _task(task),
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5721
    _collector(collector), _span(span), _mark_bit_map(mark_bit_map)
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5722
  {
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5723
    assert(_collector->_span.equals(_span) && !_span.is_empty(),
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5724
           "Inconsistency in _span");
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5725
    set_for_termination(workers->active_workers());
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5726
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5727
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5728
  OopTaskQueueSet* task_queues() { return queues(); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5729
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5730
  OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5731
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5732
  void do_work_steal(int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5733
                     CMSParDrainMarkingStackClosure* drain,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5734
                     CMSParKeepAliveClosure* keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5735
                     int* seed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5736
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5737
  virtual void work(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5738
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5739
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5740
void CMSRefProcTaskProxy::work(int i) {
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5741
  assert(_collector->_span.equals(_span), "Inconsistency in _span");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5742
  CMSParKeepAliveClosure par_keep_alive(_collector, _span,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5743
                                        _mark_bit_map,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5744
                                        &_collector->_revisitStack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5745
                                        work_queue(i));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5746
  CMSParDrainMarkingStackClosure par_drain_stack(_collector, _span,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5747
                                                 _mark_bit_map,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5748
                                                 &_collector->_revisitStack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5749
                                                 work_queue(i));
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5750
  CMSIsAliveClosure is_alive_closure(_span, _mark_bit_map);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5751
  _task.work(i, is_alive_closure, par_keep_alive, par_drain_stack);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5752
  if (_task.marks_oops_alive()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5753
    do_work_steal(i, &par_drain_stack, &par_keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5754
                  _collector->hash_seed(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5755
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5756
  assert(work_queue(i)->size() == 0, "work_queue should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5757
  assert(_collector->_overflow_list == NULL, "non-empty _overflow_list");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5758
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5759
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5760
class CMSRefEnqueueTaskProxy: public AbstractGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5761
  typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5762
  EnqueueTask& _task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5763
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5764
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5765
  CMSRefEnqueueTaskProxy(EnqueueTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5766
    : AbstractGangTask("Enqueue reference objects in parallel"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5767
      _task(task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5768
  { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5769
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5770
  virtual void work(int i)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5771
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5772
    _task.work(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5773
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5774
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5775
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5776
CMSParKeepAliveClosure::CMSParKeepAliveClosure(CMSCollector* collector,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5777
  MemRegion span, CMSBitMap* bit_map, CMSMarkStack* revisit_stack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5778
  OopTaskQueue* work_queue):
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5779
   Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5780
   _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5781
   _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5782
   _work_queue(work_queue),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5783
   _mark_and_push(collector, span, bit_map, revisit_stack, work_queue),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5784
   _low_water_mark(MIN2((uint)(work_queue->max_elems()/4),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5785
                        (uint)(CMSWorkQueueDrainThreshold * ParallelGCThreads)))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5786
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5787
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5788
// . see if we can share work_queues with ParNew? XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5789
void CMSRefProcTaskProxy::do_work_steal(int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5790
  CMSParDrainMarkingStackClosure* drain,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5791
  CMSParKeepAliveClosure* keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5792
  int* seed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5793
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5794
  NOT_PRODUCT(int num_steals = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5795
  oop obj_to_scan;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5796
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5797
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5798
    // Completely finish any left over work from (an) earlier round(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5799
    drain->trim_queue(0);
2346
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  5800
    size_t num_from_overflow_list = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  5801
                                         (size_t)ParGCDesiredObjsFromOverflowList);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5802
    // Now check if there's any work in the overflow list
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5803
    // Passing ParallelGCThreads as the third parameter, no_of_gc_threads,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5804
    // only affects the number of attempts made to get work from the
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5805
    // overflow list and does not affect the number of workers.  Just
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5806
    // pass ParallelGCThreads so this behavior is unchanged.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5807
    if (_collector->par_take_from_overflow_list(num_from_overflow_list,
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5808
                                                work_q,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5809
                                                ParallelGCThreads)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5810
      // Found something in global overflow list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5811
      // not yet ready to go stealing work from others.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5812
      // We'd like to assert(work_q->size() != 0, ...)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5813
      // because we just took work from the overflow list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5814
      // but of course we can't, since all of that might have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5815
      // been already stolen from us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5816
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5817
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5818
    // Verify that we have no work before we resort to stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5819
    assert(work_q->size() == 0, "Have work, shouldn't steal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5820
    // Try to steal from other queues that have work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5821
    if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5822
      NOT_PRODUCT(num_steals++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5823
      assert(obj_to_scan->is_oop(), "Oops, not an oop!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5824
      assert(_mark_bit_map->isMarked((HeapWord*)obj_to_scan), "Stole an unmarked oop?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5825
      // Do scanning work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5826
      obj_to_scan->oop_iterate(keep_alive);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5827
      // Loop around, finish this work, and try to steal some more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5828
    } else if (terminator()->offer_termination()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5829
      break;  // nirvana from the infinite cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5830
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5831
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5832
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5833
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5834
      gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5835
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5836
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5837
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5838
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5839
void CMSRefProcTaskExecutor::execute(ProcessTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5840
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5841
  GenCollectedHeap* gch = GenCollectedHeap::heap();
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5842
  FlexibleWorkGang* workers = gch->workers();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5843
  assert(workers != NULL, "Need parallel worker threads.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5844
  CMSRefProcTaskProxy rp_task(task, &_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5845
                              _collector.ref_processor()->span(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5846
                              _collector.markBitMap(),
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5847
                              workers, _collector.task_queues());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5848
  workers->run_task(&rp_task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5849
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5850
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5851
void CMSRefProcTaskExecutor::execute(EnqueueTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5852
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5853
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5854
  GenCollectedHeap* gch = GenCollectedHeap::heap();
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5855
  FlexibleWorkGang* workers = gch->workers();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5856
  assert(workers != NULL, "Need parallel worker threads.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5857
  CMSRefEnqueueTaskProxy enq_task(task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5858
  workers->run_task(&enq_task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5859
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5860
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5861
void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5862
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5863
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5864
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5865
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5866
  ReferenceProcessor* rp = ref_processor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5867
  assert(rp->span().equals(_span), "Spans should be equal");
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5868
  assert(!rp->enqueuing_is_done(), "Enqueuing should not be complete");
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5869
  // Process weak references.
1610
5dddd195cc86 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 1606
diff changeset
  5870
  rp->setup_policy(clear_all_soft_refs);
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5871
  verify_work_stacks_empty();
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5872
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5873
  CMSKeepAliveClosure cmsKeepAliveClosure(this, _span, &_markBitMap,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5874
                                          &_markStack, &_revisitStack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5875
                                          false /* !preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5876
  CMSDrainMarkingStackClosure cmsDrainMarkingStackClosure(this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5877
                                _span, &_markBitMap, &_markStack,
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  5878
                                &cmsKeepAliveClosure, false /* !preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5879
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5880
    TraceTime t("weak refs processing", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5881
    if (rp->processing_is_mt()) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5882
      // Set the degree of MT here.  If the discovery is done MT, there
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5883
      // may have been a different number of threads doing the discovery
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5884
      // and a different number of discovered lists may have Ref objects.
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5885
      // That is OK as long as the Reference lists are balanced (see
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5886
      // balance_all_queues() and balance_queues()).
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5887
8688
493d12ccc6db 6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents: 8684
diff changeset
  5888
      rp->set_active_mt_degree(ParallelGCThreads);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5889
      CMSRefProcTaskExecutor task_executor(*this);
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5890
      rp->process_discovered_references(&_is_alive_closure,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5891
                                        &cmsKeepAliveClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5892
                                        &cmsDrainMarkingStackClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5893
                                        &task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5894
    } else {
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5895
      rp->process_discovered_references(&_is_alive_closure,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5896
                                        &cmsKeepAliveClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5897
                                        &cmsDrainMarkingStackClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5898
                                        NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5899
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5900
    verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5901
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5902
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  5903
  if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5904
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5905
      TraceTime t("class unloading", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5906
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5907
      // Follow SystemDictionary roots and unload classes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5908
      bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5909
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5910
      // Follow CodeCache roots and unload any methods marked for unloading
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5911
      CodeCache::do_unloading(&_is_alive_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5912
                              &cmsKeepAliveClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5913
                              purged_class);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5914
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5915
      cmsDrainMarkingStackClosure.do_void();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5916
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5917
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5918
      // Update subklass/sibling/implementor links in KlassKlass descendants
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5919
      assert(!_revisitStack.isEmpty(), "revisit stack should not be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5920
      oop k;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5921
      while ((k = _revisitStack.pop()) != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5922
        ((Klass*)(oopDesc*)k)->follow_weak_klass_links(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5923
                       &_is_alive_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5924
                       &cmsKeepAliveClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5925
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5926
      assert(!ClassUnloading ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5927
             (_markStack.isEmpty() && overflow_list_is_empty()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5928
             "Should not have found new reachable objects");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5929
      assert(_revisitStack.isEmpty(), "revisit stack should have been drained");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5930
      cmsDrainMarkingStackClosure.do_void();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5931
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5932
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5933
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5934
    {
8728
3f1bcd33068e 6962931: move interned strings out of the perm gen
jcoomes
parents: 8688
diff changeset
  5935
      TraceTime t("scrub symbol table", PrintGCDetails, false, gclog_or_tty);
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7918
diff changeset
  5936
      // Clean up unreferenced symbols in symbol table.
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7918
diff changeset
  5937
      SymbolTable::unlink();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5938
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5939
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5940
8728
3f1bcd33068e 6962931: move interned strings out of the perm gen
jcoomes
parents: 8688
diff changeset
  5941
  if (should_unload_classes() || !JavaObjectsInPerm) {
3f1bcd33068e 6962931: move interned strings out of the perm gen
jcoomes
parents: 8688
diff changeset
  5942
    TraceTime t("scrub string table", PrintGCDetails, false, gclog_or_tty);
3f1bcd33068e 6962931: move interned strings out of the perm gen
jcoomes
parents: 8688
diff changeset
  5943
    // Now clean up stale oops in StringTable
3f1bcd33068e 6962931: move interned strings out of the perm gen
jcoomes
parents: 8688
diff changeset
  5944
    StringTable::unlink(&_is_alive_closure);
3f1bcd33068e 6962931: move interned strings out of the perm gen
jcoomes
parents: 8688
diff changeset
  5945
  }
3f1bcd33068e 6962931: move interned strings out of the perm gen
jcoomes
parents: 8688
diff changeset
  5946
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5947
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5948
  // Restore any preserved marks as a result of mark stack or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5949
  // work queue overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5950
  restore_preserved_marks_if_any();  // done single-threaded for now
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5951
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5952
  rp->set_enqueuing_is_done(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5953
  if (rp->processing_is_mt()) {
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  5954
    rp->balance_all_queues();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5955
    CMSRefProcTaskExecutor task_executor(*this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5956
    rp->enqueue_discovered_references(&task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5957
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5958
    rp->enqueue_discovered_references(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5959
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5960
  rp->verify_no_references_recorded();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5961
  assert(!rp->discovery_enabled(), "should have been disabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5962
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5963
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5964
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5965
void CMSCollector::check_correct_thread_executing() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5966
  Thread* t = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5967
  // Only the VM thread or the CMS thread should be here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5968
  assert(t->is_ConcurrentGC_thread() || t->is_VM_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5969
         "Unexpected thread type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5970
  // If this is the vm thread, the foreground process
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5971
  // should not be waiting.  Note that _foregroundGCIsActive is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5972
  // true while the foreground collector is waiting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5973
  if (_foregroundGCShouldWait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5974
    // We cannot be the VM thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5975
    assert(t->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5976
           "Should be CMS thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5977
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5978
    // We can be the CMS thread only if we are in a stop-world
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5979
    // phase of CMS collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5980
    if (t->is_ConcurrentGC_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5981
      assert(_collectorState == InitialMarking ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5982
             _collectorState == FinalMarking,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5983
             "Should be a stop-world phase");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5984
      // The CMS thread should be holding the CMS_token.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5985
      assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5986
             "Potential interference with concurrently "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5987
             "executing VM thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5988
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5989
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5990
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5991
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5992
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5993
void CMSCollector::sweep(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5994
  assert(_collectorState == Sweeping, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5995
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5996
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5997
  verify_overflow_empty();
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5998
  increment_sweep_count();
9623
151c0b638488 7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents: 9342
diff changeset
  5999
  TraceCMSMemoryManagerStats tms(_collectorState,GenCollectedHeap::heap()->gc_cause());
6245
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  6000
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6001
  _inter_sweep_timer.stop();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6002
  _inter_sweep_estimate.sample(_inter_sweep_timer.seconds());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6003
  size_policy()->avg_cms_free_at_sweep()->sample(_cmsGen->free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6004
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6005
  // PermGen verification support: If perm gen sweeping is disabled in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6006
  // this cycle, we preserve the perm gen object "deadness" information
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6007
  // in the perm_gen_verify_bit_map. In order to do that we traverse
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6008
  // all blocks in perm gen and mark all dead objects.
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6009
  if (verifying() && !should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6010
    assert(perm_gen_verify_bit_map()->sizeInBits() != 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6011
           "Should have already been allocated");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6012
    MarkDeadObjectsClosure mdo(this, _permGen->cmsSpace(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6013
                               markBitMap(), perm_gen_verify_bit_map());
180
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  6014
    if (asynch) {
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  6015
      CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(),
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  6016
                               bitMapLock());
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  6017
      _permGen->cmsSpace()->blk_iterate(&mdo);
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  6018
    } else {
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  6019
      // In the case of synchronous sweep, we already have
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  6020
      // the requisite locks/tokens.
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  6021
      _permGen->cmsSpace()->blk_iterate(&mdo);
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  6022
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6023
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6024
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6025
  assert(!_intra_sweep_timer.is_active(), "Should not be active");
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6026
  _intra_sweep_timer.reset();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6027
  _intra_sweep_timer.start();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6028
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6029
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6030
    CMSPhaseAccounting pa(this, "sweep", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6031
    // First sweep the old gen then the perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6032
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6033
      CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6034
                               bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6035
      sweepWork(_cmsGen, asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6036
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6037
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6038
    // Now repeat for perm gen
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6039
    if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6040
      CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6041
                             bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6042
      sweepWork(_permGen, asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6043
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6044
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6045
    // Update Universe::_heap_*_at_gc figures.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6046
    // We need all the free list locks to make the abstract state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6047
    // transition from Sweeping to Resetting. See detailed note
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6048
    // further below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6049
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6050
      CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6051
                               _permGen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6052
      // Update heap occupancy information which is used as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6053
      // input to soft ref clearing policy at the next gc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6054
      Universe::update_heap_info_at_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6055
      _collectorState = Resizing;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6056
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6057
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6058
    // already have needed locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6059
    sweepWork(_cmsGen,  asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6060
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6061
    if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6062
      sweepWork(_permGen, asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6063
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6064
    // Update heap occupancy information which is used as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6065
    // input to soft ref clearing policy at the next gc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6066
    Universe::update_heap_info_at_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6067
    _collectorState = Resizing;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6068
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6069
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6070
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6071
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6072
  _intra_sweep_timer.stop();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6073
  _intra_sweep_estimate.sample(_intra_sweep_timer.seconds());
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6074
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6075
  _inter_sweep_timer.reset();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6076
  _inter_sweep_timer.start();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6077
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6078
  update_time_of_last_gc(os::javaTimeMillis());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6079
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6080
  // NOTE on abstract state transitions:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6081
  // Mutators allocate-live and/or mark the mod-union table dirty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6082
  // based on the state of the collection.  The former is done in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6083
  // the interval [Marking, Sweeping] and the latter in the interval
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6084
  // [Marking, Sweeping).  Thus the transitions into the Marking state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6085
  // and out of the Sweeping state must be synchronously visible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6086
  // globally to the mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6087
  // The transition into the Marking state happens with the world
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6088
  // stopped so the mutators will globally see it.  Sweeping is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6089
  // done asynchronously by the background collector so the transition
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6090
  // from the Sweeping state to the Resizing state must be done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6091
  // under the freelistLock (as is the check for whether to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6092
  // allocate-live and whether to dirty the mod-union table).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6093
  assert(_collectorState == Resizing, "Change of collector state to"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6094
    " Resizing must be done under the freelistLocks (plural)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6095
6985
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
  6096
  // Now that sweeping has been completed, we clear
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
  6097
  // the incremental_collection_failed flag,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6098
  // thus inviting a younger gen collection to promote into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6099
  // this generation. If such a promotion may still fail,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6100
  // the flag will be set again when a young collection is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6101
  // attempted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6102
  GenCollectedHeap* gch = GenCollectedHeap::heap();
6985
e9364ec299ac 6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents: 6763
diff changeset
  6103
  gch->clear_incremental_collection_failed();  // Worth retrying as fresh space may have been freed up
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6104
  gch->update_full_collections_completed(_collection_count_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6105
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6106
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6107
// FIX ME!!! Looks like this belongs in CFLSpace, with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6108
// CMSGen merely delegating to it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6109
void ConcurrentMarkSweepGeneration::setNearLargestChunk() {
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6110
  double nearLargestPercent = FLSLargestBlockCoalesceProximity;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6111
  HeapWord*  minAddr        = _cmsSpace->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6112
  HeapWord*  largestAddr    =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6113
    (HeapWord*) _cmsSpace->dictionary()->findLargestDict();
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6114
  if (largestAddr == NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6115
    // The dictionary appears to be empty.  In this case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6116
    // try to coalesce at the end of the heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6117
    largestAddr = _cmsSpace->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6118
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6119
  size_t largestOffset     = pointer_delta(largestAddr, minAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6120
  size_t nearLargestOffset =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6121
    (size_t)((double)largestOffset * nearLargestPercent) - MinChunkSize;
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6122
  if (PrintFLSStatistics != 0) {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6123
    gclog_or_tty->print_cr(
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6124
      "CMS: Large Block: " PTR_FORMAT ";"
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6125
      " Proximity: " PTR_FORMAT " -> " PTR_FORMAT,
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6126
      largestAddr,
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6127
      _cmsSpace->nearLargestChunk(), minAddr + nearLargestOffset);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6128
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6129
  _cmsSpace->set_nearLargestChunk(minAddr + nearLargestOffset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6130
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6131
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6132
bool ConcurrentMarkSweepGeneration::isNearLargestChunk(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6133
  return addr >= _cmsSpace->nearLargestChunk();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6134
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6135
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6136
FreeChunk* ConcurrentMarkSweepGeneration::find_chunk_at_end() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6137
  return _cmsSpace->find_chunk_at_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6138
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6139
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6140
void ConcurrentMarkSweepGeneration::update_gc_stats(int current_level,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6141
                                                    bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6142
  // The next lower level has been collected.  Gather any statistics
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6143
  // that are of interest at this point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6144
  if (!full && (current_level + 1) == level()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6145
    // Gather statistics on the young generation collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6146
    collector()->stats().record_gc0_end(used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6147
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6148
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6149
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6150
CMSAdaptiveSizePolicy* ConcurrentMarkSweepGeneration::size_policy() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6151
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6152
  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6153
    "Wrong type of heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6154
  CMSAdaptiveSizePolicy* sp = (CMSAdaptiveSizePolicy*)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6155
    gch->gen_policy()->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6156
  assert(sp->is_gc_cms_adaptive_size_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6157
    "Wrong type of size policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6158
  return sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6159
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6160
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6161
void ConcurrentMarkSweepGeneration::rotate_debug_collection_type() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6162
  if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6163
    gclog_or_tty->print("Rotate from %d ", _debug_collection_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6164
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6165
  _debug_collection_type = (CollectionTypes) (_debug_collection_type + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6166
  _debug_collection_type =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6167
    (CollectionTypes) (_debug_collection_type % Unknown_collection_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6168
  if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6169
    gclog_or_tty->print_cr("to %d ", _debug_collection_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6170
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6171
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6172
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6173
void CMSCollector::sweepWork(ConcurrentMarkSweepGeneration* gen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6174
  bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6175
  // We iterate over the space(s) underlying this generation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6176
  // checking the mark bit map to see if the bits corresponding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6177
  // to specific blocks are marked or not. Blocks that are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6178
  // marked are live and are not swept up. All remaining blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6179
  // are swept up, with coalescing on-the-fly as we sweep up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6180
  // contiguous free and/or garbage blocks:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6181
  // We need to ensure that the sweeper synchronizes with allocators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6182
  // and stop-the-world collectors. In particular, the following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6183
  // locks are used:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6184
  // . CMS token: if this is held, a stop the world collection cannot occur
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6185
  // . freelistLock: if this is held no allocation can occur from this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6186
  //                 generation by another thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6187
  // . bitMapLock: if this is held, no other thread can access or update
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6188
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6189
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6190
  // Note that we need to hold the freelistLock if we use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6191
  // block iterate below; else the iterator might go awry if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6192
  // a mutator (or promotion) causes block contents to change
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6193
  // (for instance if the allocator divvies up a block).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6194
  // If we hold the free list lock, for all practical purposes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6195
  // young generation GC's can't occur (they'll usually need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6196
  // promote), so we might as well prevent all young generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6197
  // GC's while we do a sweeping step. For the same reason, we might
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6198
  // as well take the bit map lock for the entire duration
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6199
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6200
  // check that we hold the requisite locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6201
  assert(have_cms_token(), "Should hold cms token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6202
  assert(   (asynch && ConcurrentMarkSweepThread::cms_thread_has_cms_token())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6203
         || (!asynch && ConcurrentMarkSweepThread::vm_thread_has_cms_token()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6204
        "Should possess CMS token to sweep");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6205
  assert_lock_strong(gen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6206
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6207
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6208
  assert(!_inter_sweep_timer.is_active(), "Was switched off in an outer context");
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6209
  assert(_intra_sweep_timer.is_active(),  "Was switched on  in an outer context");
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6210
  gen->cmsSpace()->beginSweepFLCensus((float)(_inter_sweep_timer.seconds()),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6211
                                      _inter_sweep_estimate.padded_average(),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6212
                                      _intra_sweep_estimate.padded_average());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6213
  gen->setNearLargestChunk();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6214
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6215
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6216
    SweepClosure sweepClosure(this, gen, &_markBitMap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6217
                            CMSYield && asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6218
    gen->cmsSpace()->blk_iterate_careful(&sweepClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6219
    // We need to free-up/coalesce garbage/blocks from a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6220
    // co-terminal free run. This is done in the SweepClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6221
    // destructor; so, do not remove this scope, else the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6222
    // end-of-sweep-census below will be off by a little bit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6223
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6224
  gen->cmsSpace()->sweep_completed();
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6225
  gen->cmsSpace()->endSweepFLCensus(sweep_count());
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6226
  if (should_unload_classes()) {                // unloaded classes this cycle,
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6227
    _concurrent_cycles_since_last_unload = 0;   // ... reset count
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6228
  } else {                                      // did not unload classes,
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6229
    _concurrent_cycles_since_last_unload++;     // ... increment count
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6230
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6231
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6232
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6233
// Reset CMS data structures (for now just the marking bit map)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6234
// preparatory for the next cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6235
void CMSCollector::reset(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6236
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6237
  CMSAdaptiveSizePolicy* sp = size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6238
  AdaptiveSizePolicyOutput(sp, gch->total_collections());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6239
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6240
    CMSTokenSyncWithLocks ts(true, bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6241
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6242
    // If the state is not "Resetting", the foreground  thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6243
    // has done a collection and the resetting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6244
    if (_collectorState != Resetting) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6245
      assert(_collectorState == Idling, "The state should only change"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6246
        " because the foreground collector has finished the collection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6247
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6248
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6249
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6250
    // Clear the mark bitmap (no grey objects to start with)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6251
    // for the next cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6252
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6253
    CMSPhaseAccounting cmspa(this, "reset", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6254
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6255
    HeapWord* curAddr = _markBitMap.startWord();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6256
    while (curAddr < _markBitMap.endWord()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6257
      size_t remaining  = pointer_delta(_markBitMap.endWord(), curAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6258
      MemRegion chunk(curAddr, MIN2(CMSBitMapYieldQuantum, remaining));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6259
      _markBitMap.clear_large_range(chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6260
      if (ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6261
          !foregroundGCIsActive() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6262
          CMSYield) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6263
        assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6264
               "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6265
        assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6266
        bitMapLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6267
        ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6268
        ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6269
        stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6270
        if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6271
          incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6272
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6273
        icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6274
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6275
        // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6276
        for (unsigned i = 0; i < CMSYieldSleepCount &&
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6277
                         ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6278
                         !CMSCollector::foregroundGCIsActive(); ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6279
          os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6280
          ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6281
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6283
        ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6284
        bitMapLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6285
        startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6286
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6287
      curAddr = chunk.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6288
    }
5343
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  6289
    // A successful mostly concurrent collection has been done.
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  6290
    // Because only the full (i.e., concurrent mode failure) collections
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  6291
    // are being measured for gc overhead limits, clean the "near" flag
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  6292
    // and count.
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  6293
    sp->reset_gc_overhead_limit_count();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6294
    _collectorState = Idling;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6295
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6296
    // already have the lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6297
    assert(_collectorState == Resetting, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6298
    assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6299
    _markBitMap.clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6300
    _collectorState = Idling;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6301
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6302
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6303
  // Stop incremental mode after a cycle completes, so that any future cycles
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6304
  // are triggered by allocation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6305
  stop_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6306
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6307
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6308
    if (RotateCMSCollectionTypes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6309
      _cmsGen->rotate_debug_collection_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6310
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6311
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6312
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6313
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6314
void CMSCollector::do_CMS_operation(CMS_op_type op) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6315
  gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6316
  TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6317
  TraceTime t("GC", PrintGC, !PrintGCDetails, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6318
  TraceCollectorStats tcs(counters());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6319
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6320
  switch (op) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6321
    case CMS_op_checkpointRootsInitial: {
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7419
diff changeset
  6322
      SvcGCMarker sgcm(SvcGCMarker::OTHER);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6323
      checkpointRootsInitial(true);       // asynch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6324
      if (PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6325
        _cmsGen->printOccupancy("initial-mark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6326
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6327
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6328
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6329
    case CMS_op_checkpointRootsFinal: {
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7419
diff changeset
  6330
      SvcGCMarker sgcm(SvcGCMarker::OTHER);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6331
      checkpointRootsFinal(true,    // asynch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6332
                           false,   // !clear_all_soft_refs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6333
                           false);  // !init_mark_was_synchronous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6334
      if (PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6335
        _cmsGen->printOccupancy("remark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6336
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6337
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6338
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6339
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6340
      fatal("No such CMS_op");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6341
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6342
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6343
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6344
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6345
size_t const CMSCollector::skip_header_HeapWords() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6346
  return FreeChunk::header_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6347
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6348
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6349
// Try and collect here conditions that should hold when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6350
// CMS thread is exiting. The idea is that the foreground GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6351
// thread should not be blocked if it wants to terminate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6352
// the CMS thread and yet continue to run the VM for a while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6353
// after that.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6354
void CMSCollector::verify_ok_to_terminate() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6355
  assert(Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6356
         "should be called by CMS thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6357
  assert(!_foregroundGCShouldWait, "should be false");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6358
  // We could check here that all the various low-level locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6359
  // are not held by the CMS thread, but that is overkill; see
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6360
  // also CMSThread::verify_ok_to_terminate() where the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6361
  // is checked.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6362
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6363
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6364
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6365
size_t CMSCollector::block_size_using_printezis_bits(HeapWord* addr) const {
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  6366
   assert(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1),
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  6367
          "missing Printezis mark?");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6368
  HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6369
  size_t size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6370
  assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6371
         "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6372
  assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6373
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6374
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6375
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6376
// A variant of the above (block_size_using_printezis_bits()) except
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6377
// that we return 0 if the P-bits are not yet set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6378
size_t CMSCollector::block_size_if_printezis_bits(HeapWord* addr) const {
8296
b1c2163e4e59 6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents: 8076
diff changeset
  6379
  if (_markBitMap.isMarked(addr + 1)) {
b1c2163e4e59 6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents: 8076
diff changeset
  6380
    assert(_markBitMap.isMarked(addr), "P-bit can be set only for marked objects");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6381
    HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6382
    size_t size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6383
    assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6384
           "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6385
    assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6386
    return size;
8296
b1c2163e4e59 6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents: 8076
diff changeset
  6387
  }
b1c2163e4e59 6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents: 8076
diff changeset
  6388
  return 0;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6389
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6390
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6391
HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6392
  size_t sz = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6393
  oop p = (oop)addr;
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6394
  if (p->klass_or_null() != NULL && p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6395
    sz = CompactibleFreeListSpace::adjustObjectSize(p->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6396
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6397
    sz = block_size_using_printezis_bits(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6398
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6399
  assert(sz > 0, "size must be nonzero");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6400
  HeapWord* next_block = addr + sz;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6401
  HeapWord* next_card  = (HeapWord*)round_to((uintptr_t)next_block,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6402
                                             CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6403
  assert(round_down((uintptr_t)addr,      CardTableModRefBS::card_size) <
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6404
         round_down((uintptr_t)next_card, CardTableModRefBS::card_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6405
         "must be different cards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6406
  return next_card;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6407
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6408
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6409
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6410
// CMS Bit Map Wrapper /////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6411
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6412
// Construct a CMS bit map infrastructure, but don't create the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6413
// bit vector itself. That is done by a separate call CMSBitMap::allocate()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6414
// further below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6415
CMSBitMap::CMSBitMap(int shifter, int mutex_rank, const char* mutex_name):
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  6416
  _bm(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6417
  _shifter(shifter),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6418
  _lock(mutex_rank >= 0 ? new Mutex(mutex_rank, mutex_name, true) : NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6419
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6420
  _bmStartWord = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6421
  _bmWordSize  = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6422
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6423
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6424
bool CMSBitMap::allocate(MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6425
  _bmStartWord = mr.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6426
  _bmWordSize  = mr.word_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6427
  ReservedSpace brs(ReservedSpace::allocation_align_size_up(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6428
                     (_bmWordSize >> (_shifter + LogBitsPerByte)) + 1));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6429
  if (!brs.is_reserved()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6430
    warning("CMS bit map allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6431
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6432
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6433
  // For now we'll just commit all of the bit map up fromt.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6434
  // Later on we'll try to be more parsimonious with swap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6435
  if (!_virtual_space.initialize(brs, brs.size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6436
    warning("CMS bit map backing store failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6437
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6438
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6439
  assert(_virtual_space.committed_size() == brs.size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6440
         "didn't reserve backing store for all of CMS bit map?");
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  6441
  _bm.set_map((BitMap::bm_word_t*)_virtual_space.low());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6442
  assert(_virtual_space.committed_size() << (_shifter + LogBitsPerByte) >=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6443
         _bmWordSize, "inconsistency in bit map sizing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6444
  _bm.set_size(_bmWordSize >> _shifter);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6445
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6446
  // bm.clear(); // can we rely on getting zero'd memory? verify below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6447
  assert(isAllClear(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6448
         "Expected zero'd memory from ReservedSpace constructor");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6449
  assert(_bm.size() == heapWordDiffToOffsetDiff(sizeInWords()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6450
         "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6451
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6452
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6453
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6454
void CMSBitMap::dirty_range_iterate_clear(MemRegion mr, MemRegionClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6455
  HeapWord *next_addr, *end_addr, *last_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6456
  assert_locked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6457
  assert(covers(mr), "out-of-range error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6458
  // XXX assert that start and end are appropriately aligned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6459
  for (next_addr = mr.start(), end_addr = mr.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6460
       next_addr < end_addr; next_addr = last_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6461
    MemRegion dirty_region = getAndClearMarkedRegion(next_addr, end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6462
    last_addr = dirty_region.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6463
    if (!dirty_region.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6464
      cl->do_MemRegion(dirty_region);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6465
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6466
      assert(last_addr == end_addr, "program logic");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6467
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6468
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6469
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6470
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6471
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6472
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6473
void CMSBitMap::assert_locked() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6474
  CMSLockVerifier::assert_locked(lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6475
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6476
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6477
bool CMSBitMap::covers(MemRegion mr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6478
  // assert(_bm.map() == _virtual_space.low(), "map inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6479
  assert((size_t)_bm.size() == (_bmWordSize >> _shifter),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6480
         "size inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6481
  return (mr.start() >= _bmStartWord) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6482
         (mr.end()   <= endWord());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6483
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6484
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6485
bool CMSBitMap::covers(HeapWord* start, size_t size) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6486
    return (start >= _bmStartWord && (start + size) <= endWord());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6487
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6488
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6489
void CMSBitMap::verifyNoOneBitsInRange(HeapWord* left, HeapWord* right) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6490
  // verify that there are no 1 bits in the interval [left, right)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6491
  FalseBitMapClosure falseBitMapClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6492
  iterate(&falseBitMapClosure, left, right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6493
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6494
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6495
void CMSBitMap::region_invariant(MemRegion mr)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6496
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6497
  assert_locked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6498
  // mr = mr.intersection(MemRegion(_bmStartWord, _bmWordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6499
  assert(!mr.is_empty(), "unexpected empty region");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6500
  assert(covers(mr), "mr should be covered by bit map");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6501
  // convert address range into offset range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6502
  size_t start_ofs = heapWordToOffset(mr.start());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6503
  // Make sure that end() is appropriately aligned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6504
  assert(mr.end() == (HeapWord*)round_to((intptr_t)mr.end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6505
                        (1 << (_shifter+LogHeapWordSize))),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6506
         "Misaligned mr.end()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6507
  size_t end_ofs   = heapWordToOffset(mr.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6508
  assert(end_ofs > start_ofs, "Should mark at least one bit");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6509
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6510
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6511
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6512
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6513
bool CMSMarkStack::allocate(size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6514
  // allocate a stack of the requisite depth
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6515
  ReservedSpace rs(ReservedSpace::allocation_align_size_up(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6516
                   size * sizeof(oop)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6517
  if (!rs.is_reserved()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6518
    warning("CMSMarkStack allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6519
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6520
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6521
  if (!_virtual_space.initialize(rs, rs.size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6522
    warning("CMSMarkStack backing store failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6523
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6524
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6525
  assert(_virtual_space.committed_size() == rs.size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6526
         "didn't reserve backing store for all of CMS stack?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6527
  _base = (oop*)(_virtual_space.low());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6528
  _index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6529
  _capacity = size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6530
  NOT_PRODUCT(_max_depth = 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6531
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6532
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6533
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6534
// XXX FIX ME !!! In the MT case we come in here holding a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6535
// leaf lock. For printing we need to take a further lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6536
// which has lower rank. We need to recallibrate the two
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6537
// lock-ranks involved in order to be able to rpint the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6538
// messages below. (Or defer the printing to the caller.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6539
// For now we take the expedient path of just disabling the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6540
// messages for the problematic case.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6541
void CMSMarkStack::expand() {
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
  6542
  assert(_capacity <= MarkStackSizeMax, "stack bigger than permitted");
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
  6543
  if (_capacity == MarkStackSizeMax) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6544
    if (_hit_limit++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6545
      // We print a warning message only once per CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6546
      gclog_or_tty->print_cr(" (benign) Hit CMSMarkStack max size limit");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6547
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6548
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6549
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6550
  // Double capacity if possible
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
  6551
  size_t new_capacity = MIN2(_capacity*2, MarkStackSizeMax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6552
  // Do not give up existing stack until we have managed to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6553
  // get the double capacity that we desired.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6554
  ReservedSpace rs(ReservedSpace::allocation_align_size_up(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6555
                   new_capacity * sizeof(oop)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6556
  if (rs.is_reserved()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6557
    // Release the backing store associated with old stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6558
    _virtual_space.release();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6559
    // Reinitialize virtual space for new stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6560
    if (!_virtual_space.initialize(rs, rs.size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6561
      fatal("Not enough swap for expanded marking stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6562
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6563
    _base = (oop*)(_virtual_space.low());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6564
    _index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6565
    _capacity = new_capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6566
  } else if (_failed_double++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6567
    // Failed to double capacity, continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6568
    // we print a detail message only once per CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6569
    gclog_or_tty->print(" (benign) Failed to expand marking stack from "SIZE_FORMAT"K to "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6570
            SIZE_FORMAT"K",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6571
            _capacity / K, new_capacity / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6572
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6573
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6574
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6575
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6576
// Closures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6577
// XXX: there seems to be a lot of code  duplication here;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6578
// should refactor and consolidate common code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6579
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6580
// This closure is used to mark refs into the CMS generation in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6581
// the CMS bit map. Called at the first checkpoint. This closure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6582
// assumes that we do not need to re-mark dirty cards; if the CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6583
// generation on which this is used is not an oldest (modulo perm gen)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6584
// generation then this will lose younger_gen cards!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6585
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6586
MarkRefsIntoClosure::MarkRefsIntoClosure(
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6587
  MemRegion span, CMSBitMap* bitMap):
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6588
    _span(span),
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6589
    _bitMap(bitMap)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6590
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6591
    assert(_ref_processor == NULL, "deliberately left NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6592
    assert(_bitMap->covers(_span), "_bitMap/_span mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6593
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6594
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6595
void MarkRefsIntoClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6596
  // if p points into _span, then mark corresponding bit in _markBitMap
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6597
  assert(obj->is_oop(), "expected an oop");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6598
  HeapWord* addr = (HeapWord*)obj;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6599
  if (_span.contains(addr)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6600
    // this should be made more efficient
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6601
    _bitMap->mark(addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6602
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6603
}
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6604
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6605
void MarkRefsIntoClosure::do_oop(oop* p)       { MarkRefsIntoClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6606
void MarkRefsIntoClosure::do_oop(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6607
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6608
// A variant of the above, used for CMS marking verification.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6609
MarkRefsIntoVerifyClosure::MarkRefsIntoVerifyClosure(
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6610
  MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm):
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6611
    _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6612
    _verification_bm(verification_bm),
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6613
    _cms_bm(cms_bm)
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6614
{
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6615
    assert(_ref_processor == NULL, "deliberately left NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6616
    assert(_verification_bm->covers(_span), "_verification_bm/_span mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6617
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6618
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6619
void MarkRefsIntoVerifyClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6620
  // if p points into _span, then mark corresponding bit in _markBitMap
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6621
  assert(obj->is_oop(), "expected an oop");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6622
  HeapWord* addr = (HeapWord*)obj;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6623
  if (_span.contains(addr)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6624
    _verification_bm->mark(addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6625
    if (!_cms_bm->isMarked(addr)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6626
      oop(addr)->print();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6627
      gclog_or_tty->print_cr(" (" INTPTR_FORMAT " should have been marked)", addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6628
      fatal("... aborting");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6629
    }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6630
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6631
}
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6632
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6633
void MarkRefsIntoVerifyClosure::do_oop(oop* p)       { MarkRefsIntoVerifyClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6634
void MarkRefsIntoVerifyClosure::do_oop(narrowOop* p) { MarkRefsIntoVerifyClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6635
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6636
//////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6637
// MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6638
//////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6639
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6640
MarkRefsIntoAndScanClosure::MarkRefsIntoAndScanClosure(MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6641
                                                       ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6642
                                                       CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6643
                                                       CMSBitMap* mod_union_table,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6644
                                                       CMSMarkStack*  mark_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6645
                                                       CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6646
                                                       CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6647
                                                       bool should_yield,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6648
                                                       bool concurrent_precleaning):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6649
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6650
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6651
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6652
  _mark_stack(mark_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6653
  _pushAndMarkClosure(collector, span, rp, bit_map, mod_union_table,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6654
                      mark_stack, revisit_stack, concurrent_precleaning),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6655
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6656
  _concurrent_precleaning(concurrent_precleaning),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6657
  _freelistLock(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6658
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6659
  _ref_processor = rp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6660
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6661
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6662
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6663
// This closure is used to mark refs into the CMS generation at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6664
// second (final) checkpoint, and to scan and transitively follow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6665
// the unmarked oops. It is also used during the concurrent precleaning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6666
// phase while scanning objects on dirty cards in the CMS generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6667
// The marks are made in the marking bit map and the marking stack is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6668
// used for keeping the (newly) grey objects during the scan.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6669
// The parallel version (Par_...) appears further below.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6670
void MarkRefsIntoAndScanClosure::do_oop(oop obj) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6671
  if (obj != NULL) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6672
    assert(obj->is_oop(), "expected an oop");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6673
    HeapWord* addr = (HeapWord*)obj;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6674
    assert(_mark_stack->isEmpty(), "pre-condition (eager drainage)");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6675
    assert(_collector->overflow_list_is_empty(),
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6676
           "overflow list should be empty");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6677
    if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6678
        !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6679
      // mark bit map (object is now grey)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6680
      _bit_map->mark(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6681
      // push on marking stack (stack should be empty), and drain the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6682
      // stack by applying this closure to the oops in the oops popped
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6683
      // from the stack (i.e. blacken the grey objects)
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6684
      bool res = _mark_stack->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6685
      assert(res, "Should have space to push on empty stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6686
      do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6687
        oop new_oop = _mark_stack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6688
        assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6689
        assert(new_oop->is_parsable(), "Found unparsable oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6690
        assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6691
               "only grey objects on this stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6692
        // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6693
        // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6694
        new_oop->oop_iterate(&_pushAndMarkClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6695
        // check if it's time to yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6696
        do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6697
      } while (!_mark_stack->isEmpty() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6698
               (!_concurrent_precleaning && take_from_overflow_list()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6699
        // if marking stack is empty, and we are not doing this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6700
        // during precleaning, then check the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6701
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6702
    assert(_mark_stack->isEmpty(), "post-condition (eager drainage)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6703
    assert(_collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6704
           "overflow list was drained above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6705
    // We could restore evacuated mark words, if any, used for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6706
    // overflow list links here because the overflow list is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6707
    // provably empty here. That would reduce the maximum
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6708
    // size requirements for preserved_{oop,mark}_stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6709
    // But we'll just postpone it until we are all done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6710
    // so we can just stream through.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6711
    if (!_concurrent_precleaning && CMSOverflowEarlyRestoration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6712
      _collector->restore_preserved_marks_if_any();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6713
      assert(_collector->no_preserved_marks(), "No preserved marks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6714
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6715
    assert(!CMSOverflowEarlyRestoration || _collector->no_preserved_marks(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6716
           "All preserved marks should have been restored above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6717
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6718
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6719
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6720
void MarkRefsIntoAndScanClosure::do_oop(oop* p)       { MarkRefsIntoAndScanClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6721
void MarkRefsIntoAndScanClosure::do_oop(narrowOop* p) { MarkRefsIntoAndScanClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6722
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6723
void MarkRefsIntoAndScanClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6724
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6725
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6726
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6727
  assert_lock_strong(_bit_map->lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6728
  // relinquish the free_list_lock and bitMaplock()
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  6729
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6730
  _bit_map->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6731
  _freelistLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6732
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6733
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6734
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6735
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6736
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6737
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6738
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6739
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6740
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6741
  // See the comment in coordinator_yield()
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6742
  for (unsigned i = 0;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6743
       i < CMSYieldSleepCount &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6744
       ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6745
       !CMSCollector::foregroundGCIsActive();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6746
       ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6747
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6748
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6749
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6750
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6751
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6752
  _freelistLock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6753
  _bit_map->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6754
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6755
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6756
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6757
///////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6758
// Par_MarkRefsIntoAndScanClosure: a parallel version of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6759
//                                 MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6760
///////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6761
Par_MarkRefsIntoAndScanClosure::Par_MarkRefsIntoAndScanClosure(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6762
  CMSCollector* collector, MemRegion span, ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6763
  CMSBitMap* bit_map, OopTaskQueue* work_queue, CMSMarkStack*  revisit_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6764
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6765
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6766
  _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6767
  _low_water_mark(MIN2((uint)(work_queue->max_elems()/4),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6768
                       (uint)(CMSWorkQueueDrainThreshold * ParallelGCThreads))),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6769
  _par_pushAndMarkClosure(collector, span, rp, bit_map, work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6770
                          revisit_stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6771
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6772
  _ref_processor = rp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6773
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6774
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6775
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6776
// This closure is used to mark refs into the CMS generation at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6777
// second (final) checkpoint, and to scan and transitively follow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6778
// the unmarked oops. The marks are made in the marking bit map and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6779
// the work_queue is used for keeping the (newly) grey objects during
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6780
// the scan phase whence they are also available for stealing by parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6781
// threads. Since the marking bit map is shared, updates are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6782
// synchronized (via CAS).
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6783
void Par_MarkRefsIntoAndScanClosure::do_oop(oop obj) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6784
  if (obj != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6785
    // Ignore mark word because this could be an already marked oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6786
    // that may be chained at the end of the overflow list.
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  6787
    assert(obj->is_oop(true), "expected an oop");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6788
    HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6789
    if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6790
        !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6791
      // mark bit map (object will become grey):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6792
      // It is possible for several threads to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6793
      // trying to "claim" this object concurrently;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6794
      // the unique thread that succeeds in marking the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6795
      // object first will do the subsequent push on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6796
      // to the work queue (or overflow list).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6797
      if (_bit_map->par_mark(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6798
        // push on work_queue (which may not be empty), and trim the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6799
        // queue to an appropriate length by applying this closure to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6800
        // the oops in the oops popped from the stack (i.e. blacken the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6801
        // grey objects)
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6802
        bool res = _work_queue->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6803
        assert(res, "Low water mark should be less than capacity?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6804
        trim_queue(_low_water_mark);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6805
      } // Else, another thread claimed the object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6806
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6807
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6808
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6809
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6810
void Par_MarkRefsIntoAndScanClosure::do_oop(oop* p)       { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6811
void Par_MarkRefsIntoAndScanClosure::do_oop(narrowOop* p) { Par_MarkRefsIntoAndScanClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6812
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6813
// This closure is used to rescan the marked objects on the dirty cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6814
// in the mod union table and the card table proper.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6815
size_t ScanMarkedObjectsAgainCarefullyClosure::do_object_careful_m(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6816
  oop p, MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6817
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6818
  size_t size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6819
  HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6820
  DEBUG_ONLY(_collector->verify_work_stacks_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6821
  assert(_span.contains(addr), "we are scanning the CMS generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6822
  // check if it's time to yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6823
  if (do_yield_check()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6824
    // We yielded for some foreground stop-world work,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6825
    // and we have been asked to abort this ongoing preclean cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6826
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6827
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6828
  if (_bitMap->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6829
    // it's marked; is it potentially uninitialized?
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6830
    if (p->klass_or_null() != NULL) {
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  6831
      // If is_conc_safe is false, the object may be undergoing
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  6832
      // change by the VM outside a safepoint.  Don't try to
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  6833
      // scan it, but rather leave it for the remark phase.
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  6834
      if (CMSPermGenPrecleaningEnabled &&
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  6835
          (!p->is_conc_safe() || !p->is_parsable())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6836
        // Signal precleaning to redirty the card since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6837
        // the klass pointer is already installed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6838
        assert(size == 0, "Initial value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6839
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6840
        assert(p->is_parsable(), "must be parsable.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6841
        // an initialized object; ignore mark word in verification below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6842
        // since we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6843
        assert(p->is_oop(true), "should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6844
        if (p->is_objArray()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6845
          // objArrays are precisely marked; restrict scanning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6846
          // to dirty cards only.
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6847
          size = CompactibleFreeListSpace::adjustObjectSize(
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6848
                   p->oop_iterate(_scanningClosure, mr));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6849
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6850
          // A non-array may have been imprecisely marked; we need
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6851
          // to scan object in its entirety.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6852
          size = CompactibleFreeListSpace::adjustObjectSize(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6853
                   p->oop_iterate(_scanningClosure));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6854
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6855
        #ifdef DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6856
          size_t direct_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6857
            CompactibleFreeListSpace::adjustObjectSize(p->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6858
          assert(size == direct_size, "Inconsistency in size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6859
          assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6860
          if (!_bitMap->isMarked(addr+1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6861
            _bitMap->verifyNoOneBitsInRange(addr+2, addr+size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6862
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6863
            _bitMap->verifyNoOneBitsInRange(addr+2, addr+size-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6864
            assert(_bitMap->isMarked(addr+size-1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6865
                   "inconsistent Printezis mark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6866
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6867
        #endif // DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6868
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6869
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6870
      // an unitialized object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6871
      assert(_bitMap->isMarked(addr+1), "missing Printezis mark?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6872
      HeapWord* nextOneAddr = _bitMap->getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6873
      size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6874
      assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6875
             "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6876
      // Note that pre-cleaning needn't redirty the card. OopDesc::set_klass()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6877
      // will dirty the card when the klass pointer is installed in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6878
      // object (signalling the completion of initialization).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6879
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6880
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6881
    // Either a not yet marked object or an uninitialized object
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6882
    if (p->klass_or_null() == NULL || !p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6883
      // An uninitialized object, skip to the next card, since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6884
      // we may not be able to read its P-bits yet.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6885
      assert(size == 0, "Initial value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6886
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6887
      // An object not (yet) reached by marking: we merely need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6888
      // compute its size so as to go look at the next block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6889
      assert(p->is_oop(true), "should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6890
      size = CompactibleFreeListSpace::adjustObjectSize(p->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6891
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6892
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6893
  DEBUG_ONLY(_collector->verify_work_stacks_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6894
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6895
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6896
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6897
void ScanMarkedObjectsAgainCarefullyClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6898
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6899
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6900
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6901
  assert_lock_strong(_bitMap->lock());
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  6902
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6903
  // relinquish the free_list_lock and bitMaplock()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6904
  _bitMap->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6905
  _freelistLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6906
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6907
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6908
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6909
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6910
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6911
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6912
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6913
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6914
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6915
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6916
  for (unsigned i = 0; i < CMSYieldSleepCount &&
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6917
                   ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6918
                   !CMSCollector::foregroundGCIsActive(); ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6919
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6920
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6921
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6922
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6923
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6924
  _freelistLock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6925
  _bitMap->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6926
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6927
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6928
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6929
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6930
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6931
// SurvivorSpacePrecleanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6932
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6933
// This (single-threaded) closure is used to preclean the oops in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6934
// the survivor spaces.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6935
size_t SurvivorSpacePrecleanClosure::do_object_careful(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6936
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6937
  HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6938
  DEBUG_ONLY(_collector->verify_work_stacks_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6939
  assert(!_span.contains(addr), "we are scanning the survivor spaces");
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6940
  assert(p->klass_or_null() != NULL, "object should be initializd");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6941
  assert(p->is_parsable(), "must be parsable.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6942
  // an initialized object; ignore mark word in verification below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6943
  // since we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6944
  assert(p->is_oop(true), "should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6945
  // Note that we do not yield while we iterate over
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6946
  // the interior oops of p, pushing the relevant ones
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6947
  // on our marking stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6948
  size_t size = p->oop_iterate(_scanning_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6949
  do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6950
  // Observe that below, we do not abandon the preclean
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6951
  // phase as soon as we should; rather we empty the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6952
  // marking stack before returning. This is to satisfy
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6953
  // some existing assertions. In general, it may be a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6954
  // good idea to abort immediately and complete the marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6955
  // from the grey objects at a later time.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6956
  while (!_mark_stack->isEmpty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6957
    oop new_oop = _mark_stack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6958
    assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6959
    assert(new_oop->is_parsable(), "Found unparsable oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6960
    assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6961
           "only grey objects on this stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6962
    // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6963
    // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6964
    new_oop->oop_iterate(_scanning_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6965
    // check if it's time to yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6966
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6967
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6968
  unsigned int after_count =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6969
    GenCollectedHeap::heap()->total_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6970
  bool abort = (_before_count != after_count) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6971
               _collector->should_abort_preclean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6972
  return abort ? 0 : size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6973
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6974
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6975
void SurvivorSpacePrecleanClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6976
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6977
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6978
  assert_lock_strong(_bit_map->lock());
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  6979
  DEBUG_ONLY(RememberKlassesChecker smx(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6980
  // Relinquish the bit map lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6981
  _bit_map->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6982
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6983
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6984
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6985
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6986
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6987
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6988
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6989
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6990
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6991
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6992
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6993
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6994
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6995
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6996
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6997
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6998
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6999
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7000
  _bit_map->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7001
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7002
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7003
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7004
// This closure is used to rescan the marked objects on the dirty cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7005
// in the mod union table and the card table proper. In the parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7006
// case, although the bitMap is shared, we do a single read so the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7007
// isMarked() query is "safe".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7008
bool ScanMarkedObjectsAgainClosure::do_object_bm(oop p, MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7009
  // Ignore mark word because we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7010
  assert(p->is_oop_or_null(true), "expected an oop or null");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7011
  HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7012
  assert(_span.contains(addr), "we are scanning the CMS generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7013
  bool is_obj_array = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7014
  #ifdef DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7015
    if (!_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7016
      assert(_mark_stack->isEmpty(), "pre-condition (eager drainage)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7017
      assert(_collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7018
             "overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7019
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7020
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7021
  #endif // DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7022
  if (_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7023
    // Obj arrays are precisely marked, non-arrays are not;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7024
    // so we scan objArrays precisely and non-arrays in their
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7025
    // entirety.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7026
    if (p->is_objArray()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7027
      is_obj_array = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7028
      if (_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7029
        p->oop_iterate(_par_scan_closure, mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7030
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7031
        p->oop_iterate(_scan_closure, mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7032
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7033
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7034
      if (_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7035
        p->oop_iterate(_par_scan_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7036
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7037
        p->oop_iterate(_scan_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7038
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7039
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7040
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7041
  #ifdef DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7042
    if (!_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7043
      assert(_mark_stack->isEmpty(), "post-condition (eager drainage)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7044
      assert(_collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7045
             "overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7046
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7047
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7048
  #endif // DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7049
  return is_obj_array;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7050
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7051
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7052
MarkFromRootsClosure::MarkFromRootsClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7053
                        MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7054
                        CMSBitMap* bitMap, CMSMarkStack*  markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7055
                        CMSMarkStack*  revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7056
                        bool should_yield, bool verifying):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7057
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7058
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7059
  _bitMap(bitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7060
  _mut(&collector->_modUnionTable),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7061
  _markStack(markStack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7062
  _revisitStack(revisitStack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7063
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7064
  _skipBits(0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7065
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7066
  assert(_markStack->isEmpty(), "stack should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7067
  _finger = _bitMap->startWord();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7068
  _threshold = _finger;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7069
  assert(_collector->_restart_addr == NULL, "Sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7070
  assert(_span.contains(_finger), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7071
  DEBUG_ONLY(_verifying = verifying;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7072
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7073
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7074
void MarkFromRootsClosure::reset(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7075
  assert(_markStack->isEmpty(), "would cause duplicates on stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7076
  assert(_span.contains(addr), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7077
  _finger = addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7078
  _threshold = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7079
                 (intptr_t)_finger, CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7080
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7081
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7082
// Should revisit to see if this should be restructured for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7083
// greater efficiency.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7084
bool MarkFromRootsClosure::do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7085
  if (_skipBits > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7086
    _skipBits--;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7087
    return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7088
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7089
  // convert offset into a HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7090
  HeapWord* addr = _bitMap->startWord() + offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7091
  assert(_bitMap->endWord() && addr < _bitMap->endWord(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7092
         "address out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7093
  assert(_bitMap->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7094
  if (_bitMap->isMarked(addr+1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7095
    // this is an allocated but not yet initialized object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7096
    assert(_skipBits == 0, "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7097
    _skipBits = 2;  // skip next two marked bits ("Printezis-marks")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7098
    oop p = oop(addr);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  7099
    if (p->klass_or_null() == NULL || !p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7100
      DEBUG_ONLY(if (!_verifying) {)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7101
        // We re-dirty the cards on which this object lies and increase
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7102
        // the _threshold so that we'll come back to scan this object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7103
        // during the preclean or remark phase. (CMSCleanOnEnter)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7104
        if (CMSCleanOnEnter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7105
          size_t sz = _collector->block_size_using_printezis_bits(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7106
          HeapWord* end_card_addr   = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7107
                                         (intptr_t)(addr+sz), CardTableModRefBS::card_size);
991
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7108
          MemRegion redirty_range = MemRegion(addr, end_card_addr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7109
          assert(!redirty_range.is_empty(), "Arithmetical tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7110
          // Bump _threshold to end_card_addr; note that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7111
          // _threshold cannot possibly exceed end_card_addr, anyhow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7112
          // This prevents future clearing of the card as the scan proceeds
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7113
          // to the right.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7114
          assert(_threshold <= end_card_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7115
                 "Because we are just scanning into this object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7116
          if (_threshold < end_card_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7117
            _threshold = end_card_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7118
          }
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  7119
          if (p->klass_or_null() != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7120
            // Redirty the range of cards...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7121
            _mut->mark_range(redirty_range);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7122
          } // ...else the setting of klass will dirty the card anyway.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7123
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7124
      DEBUG_ONLY(})
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7125
      return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7126
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7127
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7128
  scanOopsInOop(addr);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7129
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7130
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7131
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7132
// We take a break if we've been at this for a while,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7133
// so as to avoid monopolizing the locks involved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7134
void MarkFromRootsClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7135
  // First give up the locks, then yield, then re-lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7136
  // We should probably use a constructor/destructor idiom to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7137
  // do this unlock/lock or modify the MutexUnlocker class to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7138
  // serve our purpose. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7139
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7140
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7141
  assert_lock_strong(_bitMap->lock());
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7142
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7143
  _bitMap->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7144
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7145
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7146
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7147
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7148
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7149
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7150
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7151
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7152
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7153
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7154
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7155
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7156
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7157
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7158
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7159
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7160
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7161
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7162
  _bitMap->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7163
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7164
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7165
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7166
void MarkFromRootsClosure::scanOopsInOop(HeapWord* ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7167
  assert(_bitMap->isMarked(ptr), "expected bit to be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7168
  assert(_markStack->isEmpty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7169
         "should drain stack to limit stack usage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7170
  // convert ptr to an oop preparatory to scanning
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7171
  oop obj = oop(ptr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7172
  // Ignore mark word in verification below, since we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7173
  // may be running concurrent with mutators.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7174
  assert(obj->is_oop(true), "should be an oop");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7175
  assert(_finger <= ptr, "_finger runneth ahead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7176
  // advance the finger to right end of this object
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7177
  _finger = ptr + obj->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7178
  assert(_finger > ptr, "we just incremented it above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7179
  // On large heaps, it may take us some time to get through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7180
  // the marking phase (especially if running iCMS). During
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7181
  // this time it's possible that a lot of mutations have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7182
  // accumulated in the card table and the mod union table --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7183
  // these mutation records are redundant until we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7184
  // actually traced into the corresponding card.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7185
  // Here, we check whether advancing the finger would make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7186
  // us cross into a new card, and if so clear corresponding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7187
  // cards in the MUT (preclean them in the card-table in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7188
  // future).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7189
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7190
  DEBUG_ONLY(if (!_verifying) {)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7191
    // The clean-on-enter optimization is disabled by default,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7192
    // until we fix 6178663.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7193
    if (CMSCleanOnEnter && (_finger > _threshold)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7194
      // [_threshold, _finger) represents the interval
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7195
      // of cards to be cleared  in MUT (or precleaned in card table).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7196
      // The set of cards to be cleared is all those that overlap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7197
      // with the interval [_threshold, _finger); note that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7198
      // _threshold is always kept card-aligned but _finger isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7199
      // always card-aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7200
      HeapWord* old_threshold = _threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7201
      assert(old_threshold == (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7202
              (intptr_t)old_threshold, CardTableModRefBS::card_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7203
             "_threshold should always be card-aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7204
      _threshold = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7205
                     (intptr_t)_finger, CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7206
      MemRegion mr(old_threshold, _threshold);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7207
      assert(!mr.is_empty(), "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7208
      assert(_span.contains(mr), "Should clear within span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7209
      // XXX When _finger crosses from old gen into perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7210
      // we may be doing unnecessary cleaning; do better in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7211
      // future by detecting that condition and clearing fewer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7212
      // MUT/CT entries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7213
      _mut->clear_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7214
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7215
  DEBUG_ONLY(})
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7216
  // Note: the finger doesn't advance while we drain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7217
  // the stack below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7218
  PushOrMarkClosure pushOrMarkClosure(_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7219
                                      _span, _bitMap, _markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7220
                                      _revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7221
                                      _finger, this);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7222
  bool res = _markStack->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7223
  assert(res, "Empty non-zero size stack should have space for single push");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7224
  while (!_markStack->isEmpty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7225
    oop new_oop = _markStack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7226
    // Skip verifying header mark word below because we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7227
    // running concurrent with mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7228
    assert(new_oop->is_oop(true), "Oops! expected to pop an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7229
    // now scan this oop's oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7230
    new_oop->oop_iterate(&pushOrMarkClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7231
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7232
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7233
  assert(_markStack->isEmpty(), "tautology, emphasizing post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7234
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7235
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7236
Par_MarkFromRootsClosure::Par_MarkFromRootsClosure(CMSConcMarkingTask* task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7237
                       CMSCollector* collector, MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7238
                       CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7239
                       OopTaskQueue* work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7240
                       CMSMarkStack*  overflow_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7241
                       CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7242
                       bool should_yield):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7243
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7244
  _whole_span(collector->_span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7245
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7246
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7247
  _mut(&collector->_modUnionTable),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7248
  _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7249
  _overflow_stack(overflow_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7250
  _revisit_stack(revisit_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7251
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7252
  _skip_bits(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7253
  _task(task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7254
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7255
  assert(_work_queue->size() == 0, "work_queue should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7256
  _finger = span.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7257
  _threshold = _finger;     // XXX Defer clear-on-enter optimization for now
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7258
  assert(_span.contains(_finger), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7259
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7260
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7261
// Should revisit to see if this should be restructured for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7262
// greater efficiency.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7263
bool Par_MarkFromRootsClosure::do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7264
  if (_skip_bits > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7265
    _skip_bits--;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7266
    return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7267
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7268
  // convert offset into a HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7269
  HeapWord* addr = _bit_map->startWord() + offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7270
  assert(_bit_map->endWord() && addr < _bit_map->endWord(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7271
         "address out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7272
  assert(_bit_map->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7273
  if (_bit_map->isMarked(addr+1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7274
    // this is an allocated object that might not yet be initialized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7275
    assert(_skip_bits == 0, "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7276
    _skip_bits = 2;  // skip next two marked bits ("Printezis-marks")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7277
    oop p = oop(addr);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  7278
    if (p->klass_or_null() == NULL || !p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7279
      // in the case of Clean-on-Enter optimization, redirty card
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7280
      // and avoid clearing card by increasing  the threshold.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7281
      return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7282
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7283
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7284
  scan_oops_in_oop(addr);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7285
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7286
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7287
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7288
void Par_MarkFromRootsClosure::scan_oops_in_oop(HeapWord* ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7289
  assert(_bit_map->isMarked(ptr), "expected bit to be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7290
  // Should we assert that our work queue is empty or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7291
  // below some drain limit?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7292
  assert(_work_queue->size() == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7293
         "should drain stack to limit stack usage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7294
  // convert ptr to an oop preparatory to scanning
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7295
  oop obj = oop(ptr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7296
  // Ignore mark word in verification below, since we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7297
  // may be running concurrent with mutators.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7298
  assert(obj->is_oop(true), "should be an oop");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7299
  assert(_finger <= ptr, "_finger runneth ahead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7300
  // advance the finger to right end of this object
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7301
  _finger = ptr + obj->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7302
  assert(_finger > ptr, "we just incremented it above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7303
  // On large heaps, it may take us some time to get through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7304
  // the marking phase (especially if running iCMS). During
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7305
  // this time it's possible that a lot of mutations have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7306
  // accumulated in the card table and the mod union table --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7307
  // these mutation records are redundant until we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7308
  // actually traced into the corresponding card.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7309
  // Here, we check whether advancing the finger would make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7310
  // us cross into a new card, and if so clear corresponding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7311
  // cards in the MUT (preclean them in the card-table in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7312
  // future).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7313
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7314
  // The clean-on-enter optimization is disabled by default,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7315
  // until we fix 6178663.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7316
  if (CMSCleanOnEnter && (_finger > _threshold)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7317
    // [_threshold, _finger) represents the interval
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7318
    // of cards to be cleared  in MUT (or precleaned in card table).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7319
    // The set of cards to be cleared is all those that overlap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7320
    // with the interval [_threshold, _finger); note that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7321
    // _threshold is always kept card-aligned but _finger isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7322
    // always card-aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7323
    HeapWord* old_threshold = _threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7324
    assert(old_threshold == (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7325
            (intptr_t)old_threshold, CardTableModRefBS::card_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7326
           "_threshold should always be card-aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7327
    _threshold = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7328
                   (intptr_t)_finger, CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7329
    MemRegion mr(old_threshold, _threshold);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7330
    assert(!mr.is_empty(), "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7331
    assert(_span.contains(mr), "Should clear within span"); // _whole_span ??
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7332
    // XXX When _finger crosses from old gen into perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7333
    // we may be doing unnecessary cleaning; do better in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7334
    // future by detecting that condition and clearing fewer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7335
    // MUT/CT entries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7336
    _mut->clear_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7337
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7338
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7339
  // Note: the local finger doesn't advance while we drain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7340
  // the stack below, but the global finger sure can and will.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7341
  HeapWord** gfa = _task->global_finger_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7342
  Par_PushOrMarkClosure pushOrMarkClosure(_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7343
                                      _span, _bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7344
                                      _work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7345
                                      _overflow_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7346
                                      _revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7347
                                      _finger,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7348
                                      gfa, this);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7349
  bool res = _work_queue->push(obj);   // overflow could occur here
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7350
  assert(res, "Will hold once we use workqueues");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7351
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7352
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7353
    if (!_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7354
      // We emptied our work_queue; check if there's stuff that can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7355
      // be gotten from the overflow stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7356
      if (CMSConcMarkingTask::get_work_from_overflow_stack(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7357
            _overflow_stack, _work_queue)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7358
        do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7359
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7360
      } else {  // done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7361
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7362
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7363
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7364
    // Skip verifying header mark word below because we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7365
    // running concurrent with mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7366
    assert(new_oop->is_oop(true), "Oops! expected to pop an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7367
    // now scan this oop's oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7368
    new_oop->oop_iterate(&pushOrMarkClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7369
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7370
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7371
  assert(_work_queue->size() == 0, "tautology, emphasizing post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7372
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7373
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7374
// Yield in response to a request from VM Thread or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7375
// from mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7376
void Par_MarkFromRootsClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7377
  assert(_task != NULL, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7378
  _task->yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7379
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7380
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7381
// A variant of the above used for verifying CMS marking work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7382
MarkFromRootsVerifyClosure::MarkFromRootsVerifyClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7383
                        MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7384
                        CMSBitMap* verification_bm, CMSBitMap* cms_bm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7385
                        CMSMarkStack*  mark_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7386
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7387
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7388
  _verification_bm(verification_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7389
  _cms_bm(cms_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7390
  _mark_stack(mark_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7391
  _pam_verify_closure(collector, span, verification_bm, cms_bm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7392
                      mark_stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7393
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7394
  assert(_mark_stack->isEmpty(), "stack should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7395
  _finger = _verification_bm->startWord();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7396
  assert(_collector->_restart_addr == NULL, "Sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7397
  assert(_span.contains(_finger), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7398
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7399
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7400
void MarkFromRootsVerifyClosure::reset(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7401
  assert(_mark_stack->isEmpty(), "would cause duplicates on stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7402
  assert(_span.contains(addr), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7403
  _finger = addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7404
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7405
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7406
// Should revisit to see if this should be restructured for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7407
// greater efficiency.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7408
bool MarkFromRootsVerifyClosure::do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7409
  // convert offset into a HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7410
  HeapWord* addr = _verification_bm->startWord() + offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7411
  assert(_verification_bm->endWord() && addr < _verification_bm->endWord(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7412
         "address out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7413
  assert(_verification_bm->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7414
  assert(_cms_bm->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7415
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7416
  assert(_mark_stack->isEmpty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7417
         "should drain stack to limit stack usage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7418
  // convert addr to an oop preparatory to scanning
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7419
  oop obj = oop(addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7420
  assert(obj->is_oop(), "should be an oop");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7421
  assert(_finger <= addr, "_finger runneth ahead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7422
  // advance the finger to right end of this object
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7423
  _finger = addr + obj->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7424
  assert(_finger > addr, "we just incremented it above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7425
  // Note: the finger doesn't advance while we drain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7426
  // the stack below.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7427
  bool res = _mark_stack->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7428
  assert(res, "Empty non-zero size stack should have space for single push");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7429
  while (!_mark_stack->isEmpty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7430
    oop new_oop = _mark_stack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7431
    assert(new_oop->is_oop(), "Oops! expected to pop an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7432
    // now scan this oop's oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7433
    new_oop->oop_iterate(&_pam_verify_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7434
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7435
  assert(_mark_stack->isEmpty(), "tautology, emphasizing post-condition");
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7436
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7437
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7438
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7439
PushAndMarkVerifyClosure::PushAndMarkVerifyClosure(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7440
  CMSCollector* collector, MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7441
  CMSBitMap* verification_bm, CMSBitMap* cms_bm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7442
  CMSMarkStack*  mark_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7443
  OopClosure(collector->ref_processor()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7444
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7445
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7446
  _verification_bm(verification_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7447
  _cms_bm(cms_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7448
  _mark_stack(mark_stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7449
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7450
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7451
void PushAndMarkVerifyClosure::do_oop(oop* p)       { PushAndMarkVerifyClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7452
void PushAndMarkVerifyClosure::do_oop(narrowOop* p) { PushAndMarkVerifyClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7453
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7454
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7455
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7456
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7457
void PushAndMarkVerifyClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7458
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7459
  HeapWord* ra = (HeapWord*)_mark_stack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7460
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7461
  _mark_stack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7462
  _mark_stack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7463
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7464
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7465
void PushAndMarkVerifyClosure::do_oop(oop obj) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7466
  assert(obj->is_oop_or_null(), "expected an oop or NULL");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7467
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7468
  if (_span.contains(addr) && !_verification_bm->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7469
    // Oop lies in _span and isn't yet grey or black
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7470
    _verification_bm->mark(addr);            // now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7471
    if (!_cms_bm->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7472
      oop(addr)->print();
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7473
      gclog_or_tty->print_cr(" (" INTPTR_FORMAT " should have been marked)",
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7474
                             addr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7475
      fatal("... aborting");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7476
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7477
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7478
    if (!_mark_stack->push(obj)) { // stack overflow
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7479
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7480
        gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7481
                               SIZE_FORMAT, _mark_stack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7482
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7483
      assert(_mark_stack->isFull(), "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7484
      handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7485
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7486
    // anything including and to the right of _finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7487
    // will be scanned as we iterate over the remainder of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7488
    // bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7489
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7490
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7491
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7492
PushOrMarkClosure::PushOrMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7493
                     MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7494
                     CMSBitMap* bitMap, CMSMarkStack*  markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7495
                     CMSMarkStack*  revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7496
                     HeapWord* finger, MarkFromRootsClosure* parent) :
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7497
  KlassRememberingOopClosure(collector, collector->ref_processor(), revisitStack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7498
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7499
  _bitMap(bitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7500
  _markStack(markStack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7501
  _finger(finger),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7502
  _parent(parent)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7503
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7504
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7505
Par_PushOrMarkClosure::Par_PushOrMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7506
                     MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7507
                     CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7508
                     OopTaskQueue* work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7509
                     CMSMarkStack*  overflow_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7510
                     CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7511
                     HeapWord* finger,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7512
                     HeapWord** global_finger_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7513
                     Par_MarkFromRootsClosure* parent) :
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7514
  Par_KlassRememberingOopClosure(collector,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7515
                            collector->ref_processor(),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7516
                            revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7517
  _whole_span(collector->_span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7518
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7519
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7520
  _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7521
  _overflow_stack(overflow_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7522
  _finger(finger),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7523
  _global_finger_addr(global_finger_addr),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7524
  _parent(parent)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7525
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7526
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  7527
// Assumes thread-safe access by callers, who are
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  7528
// responsible for mutual exclusion.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7529
void CMSCollector::lower_restart_addr(HeapWord* low) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7530
  assert(_span.contains(low), "Out of bounds addr");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7531
  if (_restart_addr == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7532
    _restart_addr = low;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7533
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7534
    _restart_addr = MIN2(_restart_addr, low);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7535
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7536
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7537
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7538
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7539
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7540
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7541
void PushOrMarkClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7542
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7543
  HeapWord* ra = (HeapWord*)_markStack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7544
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7545
  _markStack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7546
  _markStack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7547
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7548
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7549
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7550
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7551
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7552
void Par_PushOrMarkClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7553
  // We need to do this under a mutex to prevent other
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  7554
  // workers from interfering with the work done below.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7555
  MutexLockerEx ml(_overflow_stack->par_lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7556
                   Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7557
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7558
  HeapWord* ra = (HeapWord*)_overflow_stack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7559
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7560
  _overflow_stack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7561
  _overflow_stack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7562
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7563
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7564
void PushOrMarkClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7565
  // Ignore mark word because we are running concurrent with mutators.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7566
  assert(obj->is_oop_or_null(true), "expected an oop or NULL");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7567
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7568
  if (_span.contains(addr) && !_bitMap->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7569
    // Oop lies in _span and isn't yet grey or black
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7570
    _bitMap->mark(addr);            // now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7571
    if (addr < _finger) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7572
      // the bit map iteration has already either passed, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7573
      // sampled, this bit in the bit map; we'll need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7574
      // use the marking stack to scan this oop's oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7575
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7576
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7577
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7578
            _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7579
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7580
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7581
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7582
      )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7583
      if (simulate_overflow || !_markStack->push(obj)) { // stack overflow
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7584
        if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7585
          gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7586
                                 SIZE_FORMAT, _markStack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7587
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7588
        assert(simulate_overflow || _markStack->isFull(), "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7589
        handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7590
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7591
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7592
    // anything including and to the right of _finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7593
    // will be scanned as we iterate over the remainder of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7594
    // bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7595
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7596
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7597
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7598
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7599
void PushOrMarkClosure::do_oop(oop* p)       { PushOrMarkClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7600
void PushOrMarkClosure::do_oop(narrowOop* p) { PushOrMarkClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7601
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7602
void Par_PushOrMarkClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7603
  // Ignore mark word because we are running concurrent with mutators.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7604
  assert(obj->is_oop_or_null(true), "expected an oop or NULL");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7605
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7606
  if (_whole_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7607
    // Oop lies in _span and isn't yet grey or black
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7608
    // We read the global_finger (volatile read) strictly after marking oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7609
    bool res = _bit_map->par_mark(addr);    // now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7610
    volatile HeapWord** gfa = (volatile HeapWord**)_global_finger_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7611
    // Should we push this marked oop on our stack?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7612
    // -- if someone else marked it, nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7613
    // -- if target oop is above global finger nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7614
    // -- if target oop is in chunk and above local finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7615
    //      then nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7616
    // -- else push on work queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7617
    if (   !res       // someone else marked it, they will deal with it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7618
        || (addr >= *gfa)  // will be scanned in a later task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7619
        || (_span.contains(addr) && addr >= _finger)) { // later in this chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7620
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7621
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7622
    // the bit map iteration has already either passed, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7623
    // sampled, this bit in the bit map; we'll need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7624
    // use the marking stack to scan this oop's oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7625
    bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7626
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7627
      if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7628
          _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7629
        // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7630
        simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7631
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7632
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7633
    if (simulate_overflow ||
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7634
        !(_work_queue->push(obj) || _overflow_stack->par_push(obj))) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7635
      // stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7636
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7637
        gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7638
                               SIZE_FORMAT, _overflow_stack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7639
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7640
      // We cannot assert that the overflow stack is full because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7641
      // it may have been emptied since.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7642
      assert(simulate_overflow ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7643
             _work_queue->size() == _work_queue->max_elems(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7644
            "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7645
      handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7646
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7647
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7648
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7649
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7650
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7651
void Par_PushOrMarkClosure::do_oop(oop* p)       { Par_PushOrMarkClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7652
void Par_PushOrMarkClosure::do_oop(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7653
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7654
KlassRememberingOopClosure::KlassRememberingOopClosure(CMSCollector* collector,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7655
                                             ReferenceProcessor* rp,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7656
                                             CMSMarkStack* revisit_stack) :
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7657
  OopClosure(rp),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7658
  _collector(collector),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7659
  _revisit_stack(revisit_stack),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7660
  _should_remember_klasses(collector->should_unload_classes()) {}
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7661
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7662
PushAndMarkClosure::PushAndMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7663
                                       MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7664
                                       ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7665
                                       CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7666
                                       CMSBitMap* mod_union_table,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7667
                                       CMSMarkStack*  mark_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7668
                                       CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7669
                                       bool           concurrent_precleaning):
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7670
  KlassRememberingOopClosure(collector, rp, revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7671
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7672
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7673
  _mod_union_table(mod_union_table),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7674
  _mark_stack(mark_stack),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7675
  _concurrent_precleaning(concurrent_precleaning)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7676
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7677
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7678
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7679
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7680
// Grey object rescan during pre-cleaning and second checkpoint phases --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7681
// the non-parallel version (the parallel version appears further below.)
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7682
void PushAndMarkClosure::do_oop(oop obj) {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7683
  // Ignore mark word verification. If during concurrent precleaning,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7684
  // the object monitor may be locked. If during the checkpoint
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7685
  // phases, the object may already have been reached by a  different
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7686
  // path and may be at the end of the global overflow list (so
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7687
  // the mark word may be NULL).
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7688
  assert(obj->is_oop_or_null(true /* ignore mark word */),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7689
         "expected an oop or NULL");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7690
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7691
  // Check if oop points into the CMS generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7692
  // and is not marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7693
  if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7694
    // a white object ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7695
    _bit_map->mark(addr);         // ... now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7696
    // push on the marking stack (grey set)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7697
    bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7698
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7699
      if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7700
          _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7701
        // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7702
        simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7703
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7704
    )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7705
    if (simulate_overflow || !_mark_stack->push(obj)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7706
      if (_concurrent_precleaning) {
991
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7707
         // During precleaning we can just dirty the appropriate card(s)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7708
         // in the mod union table, thus ensuring that the object remains
991
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7709
         // in the grey set  and continue. In the case of object arrays
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7710
         // we need to dirty all of the cards that the object spans,
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7711
         // since the rescan of object arrays will be limited to the
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7712
         // dirty cards.
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7713
         // Note that no one can be intefering with us in this action
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7714
         // of dirtying the mod union table, so no locking or atomics
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7715
         // are required.
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7716
         if (obj->is_objArray()) {
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7717
           size_t sz = obj->size();
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7718
           HeapWord* end_card_addr = (HeapWord*)round_to(
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7719
                                        (intptr_t)(addr+sz), CardTableModRefBS::card_size);
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7720
           MemRegion redirty_range = MemRegion(addr, end_card_addr);
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7721
           assert(!redirty_range.is_empty(), "Arithmetical tautology");
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7722
           _mod_union_table->mark_range(redirty_range);
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7723
         } else {
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7724
           _mod_union_table->mark(addr);
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7725
         }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7726
         _collector->_ser_pmc_preclean_ovflw++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7727
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7728
         // During the remark phase, we need to remember this oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7729
         // in the overflow list.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7730
         _collector->push_on_overflow_list(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7731
         _collector->_ser_pmc_remark_ovflw++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7732
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7733
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7734
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7735
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7736
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7737
Par_PushAndMarkClosure::Par_PushAndMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7738
                                               MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7739
                                               ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7740
                                               CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7741
                                               OopTaskQueue* work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7742
                                               CMSMarkStack* revisit_stack):
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7743
  Par_KlassRememberingOopClosure(collector, rp, revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7744
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7745
  _bit_map(bit_map),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7746
  _work_queue(work_queue)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7747
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7748
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7749
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7750
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7751
void PushAndMarkClosure::do_oop(oop* p)       { PushAndMarkClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7752
void PushAndMarkClosure::do_oop(narrowOop* p) { PushAndMarkClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7753
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7754
// Grey object rescan during second checkpoint phase --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7755
// the parallel version.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7756
void Par_PushAndMarkClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7757
  // In the assert below, we ignore the mark word because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7758
  // this oop may point to an already visited object that is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7759
  // on the overflow stack (in which case the mark word has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7760
  // been hijacked for chaining into the overflow stack --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7761
  // if this is the last object in the overflow stack then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7762
  // its mark word will be NULL). Because this object may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7763
  // have been subsequently popped off the global overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7764
  // stack, and the mark word possibly restored to the prototypical
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7765
  // value, by the time we get to examined this failing assert in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7766
  // the debugger, is_oop_or_null(false) may subsequently start
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7767
  // to hold.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7768
  assert(obj->is_oop_or_null(true),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7769
         "expected an oop or NULL");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7770
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7771
  // Check if oop points into the CMS generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7772
  // and is not marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7773
  if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7774
    // a white object ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7775
    // If we manage to "claim" the object, by being the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7776
    // first thread to mark it, then we push it on our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7777
    // marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7778
    if (_bit_map->par_mark(addr)) {     // ... now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7779
      // push on work queue (grey set)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7780
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7781
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7782
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7783
            _collector->par_simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7784
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7785
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7786
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7787
      )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7788
      if (simulate_overflow || !_work_queue->push(obj)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7789
        _collector->par_push_on_overflow_list(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7790
        _collector->_par_pmc_remark_ovflw++; //  imprecise OK: no need to CAS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7791
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7792
    } // Else, some other thread got there first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7793
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7794
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7795
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7796
void Par_PushAndMarkClosure::do_oop(oop* p)       { Par_PushAndMarkClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7797
void Par_PushAndMarkClosure::do_oop(narrowOop* p) { Par_PushAndMarkClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7798
3696
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7799
void PushAndMarkClosure::remember_mdo(DataLayout* v) {
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7800
  // TBD
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7801
}
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7802
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7803
void Par_PushAndMarkClosure::remember_mdo(DataLayout* v) {
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7804
  // TBD
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7805
}
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7806
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7807
void CMSPrecleanRefsYieldClosure::do_yield_work() {
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7808
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7809
  Mutex* bml = _collector->bitMapLock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7810
  assert_lock_strong(bml);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7811
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7812
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7813
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7814
  bml->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7815
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7816
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7817
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7818
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7819
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7820
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7821
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7822
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7823
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7824
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7825
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7826
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7827
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7828
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7829
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7830
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7831
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7832
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7833
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7834
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7835
  bml->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7836
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7837
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7838
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7839
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7840
bool CMSPrecleanRefsYieldClosure::should_return() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7841
  if (ConcurrentMarkSweepThread::should_yield()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7842
    do_yield_work();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7843
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7844
  return _collector->foregroundGCIsActive();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7845
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7846
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7847
void MarkFromDirtyCardsClosure::do_MemRegion(MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7848
  assert(((size_t)mr.start())%CardTableModRefBS::card_size_in_words == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7849
         "mr should be aligned to start at a card boundary");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7850
  // We'd like to assert:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7851
  // assert(mr.word_size()%CardTableModRefBS::card_size_in_words == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7852
  //        "mr should be a range of cards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7853
  // However, that would be too strong in one case -- the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7854
  // partition ends at _unallocated_block which, in general, can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7855
  // an arbitrary boundary, not necessarily card aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7856
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7857
    _num_dirty_cards +=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7858
         mr.word_size()/CardTableModRefBS::card_size_in_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7859
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7860
  _space->object_iterate_mem(mr, &_scan_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7861
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7862
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7863
SweepClosure::SweepClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7864
                           ConcurrentMarkSweepGeneration* g,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7865
                           CMSBitMap* bitMap, bool should_yield) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7866
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7867
  _g(g),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7868
  _sp(g->cmsSpace()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7869
  _limit(_sp->sweep_limit()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7870
  _freelistLock(_sp->freelistLock()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7871
  _bitMap(bitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7872
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7873
  _inFreeRange(false),           // No free range at beginning of sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7874
  _freeRangeInFreeLists(false),  // No free range at beginning of sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7875
  _lastFreeRangeCoalesced(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7876
  _freeFinger(g->used_region().start())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7877
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7878
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7879
    _numObjectsFreed = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7880
    _numWordsFreed   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7881
    _numObjectsLive = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7882
    _numWordsLive = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7883
    _numObjectsAlreadyFree = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7884
    _numWordsAlreadyFree = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7885
    _last_fc = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7886
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7887
    _sp->initializeIndexedFreeListArrayReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7888
    _sp->dictionary()->initializeDictReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7889
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7890
  assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7891
         "sweep _limit out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7892
  if (CMSTraceSweeper) {
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7893
    gclog_or_tty->print_cr("\n====================\nStarting new sweep with limit " PTR_FORMAT,
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7894
                        _limit);
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7895
  }
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7896
}
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7897
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7898
void SweepClosure::print_on(outputStream* st) const {
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7899
  tty->print_cr("_sp = [" PTR_FORMAT "," PTR_FORMAT ")",
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7900
                _sp->bottom(), _sp->end());
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7901
  tty->print_cr("_limit = " PTR_FORMAT, _limit);
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7902
  tty->print_cr("_freeFinger = " PTR_FORMAT, _freeFinger);
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7903
  NOT_PRODUCT(tty->print_cr("_last_fc = " PTR_FORMAT, _last_fc);)
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7904
  tty->print_cr("_inFreeRange = %d, _freeRangeInFreeLists = %d, _lastFreeRangeCoalesced = %d",
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7905
                _inFreeRange, _freeRangeInFreeLists, _lastFreeRangeCoalesced);
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7906
}
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7907
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7908
#ifndef PRODUCT
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7909
// Assertion checking only:  no useful work in product mode --
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7910
// however, if any of the flags below become product flags,
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7911
// you may need to review this code to see if it needs to be
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7912
// enabled in product mode.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7913
SweepClosure::~SweepClosure() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7914
  assert_lock_strong(_freelistLock);
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  7915
  assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  7916
         "sweep _limit out of bounds");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7917
  if (inFreeRange()) {
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7918
    warning("inFreeRange() should have been reset; dumping state of SweepClosure");
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7919
    print();
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7920
    ShouldNotReachHere();
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7921
  }
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7922
  if (Verbose && PrintGC) {
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7923
    gclog_or_tty->print("Collected "SIZE_FORMAT" objects, " SIZE_FORMAT " bytes",
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7924
                        _numObjectsFreed, _numWordsFreed*sizeof(HeapWord));
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7925
    gclog_or_tty->print_cr("\nLive "SIZE_FORMAT" objects,  "
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7926
                           SIZE_FORMAT" bytes  "
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7927
      "Already free "SIZE_FORMAT" objects, "SIZE_FORMAT" bytes",
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7928
      _numObjectsLive, _numWordsLive*sizeof(HeapWord),
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7929
      _numObjectsAlreadyFree, _numWordsAlreadyFree*sizeof(HeapWord));
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7930
    size_t totalBytes = (_numWordsFreed + _numWordsLive + _numWordsAlreadyFree)
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7931
                        * sizeof(HeapWord);
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7932
    gclog_or_tty->print_cr("Total sweep: "SIZE_FORMAT" bytes", totalBytes);
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7933
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7934
    if (PrintCMSStatistics && CMSVerifyReturnedBytes) {
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7935
      size_t indexListReturnedBytes = _sp->sumIndexedFreeListArrayReturnedBytes();
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7936
      size_t dictReturnedBytes = _sp->dictionary()->sumDictReturnedBytes();
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7937
      size_t returnedBytes = indexListReturnedBytes + dictReturnedBytes;
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7938
      gclog_or_tty->print("Returned "SIZE_FORMAT" bytes", returnedBytes);
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7939
      gclog_or_tty->print("   Indexed List Returned "SIZE_FORMAT" bytes",
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7940
        indexListReturnedBytes);
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7941
      gclog_or_tty->print_cr("        Dictionary Returned "SIZE_FORMAT" bytes",
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7942
        dictReturnedBytes);
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7943
    }
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7944
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7945
  if (CMSTraceSweeper) {
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7946
    gclog_or_tty->print_cr("end of sweep with _limit = " PTR_FORMAT "\n================",
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7947
                           _limit);
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7948
  }
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7949
}
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  7950
#endif  // PRODUCT
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7951
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7952
void SweepClosure::initialize_free_range(HeapWord* freeFinger,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7953
    bool freeRangeInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7954
  if (CMSTraceSweeper) {
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  7955
    gclog_or_tty->print("---- Start free range at 0x%x with free block (%d)\n",
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  7956
               freeFinger, freeRangeInFreeLists);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7957
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7958
  assert(!inFreeRange(), "Trampling existing free range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7959
  set_inFreeRange(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7960
  set_lastFreeRangeCoalesced(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7961
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7962
  set_freeFinger(freeFinger);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7963
  set_freeRangeInFreeLists(freeRangeInFreeLists);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7964
  if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7965
    if (freeRangeInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7966
      FreeChunk* fc = (FreeChunk*) freeFinger;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7967
      assert(fc->isFree(), "A chunk on the free list should be free.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7968
      assert(fc->size() > 0, "Free range should have a size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7969
      assert(_sp->verifyChunkInFreeLists(fc), "Chunk is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7970
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7971
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7972
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7973
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7974
// Note that the sweeper runs concurrently with mutators. Thus,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7975
// it is possible for direct allocation in this generation to happen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7976
// in the middle of the sweep. Note that the sweeper also coalesces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7977
// contiguous free blocks. Thus, unless the sweeper and the allocator
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7978
// synchronize appropriately freshly allocated blocks may get swept up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7979
// This is accomplished by the sweeper locking the free lists while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7980
// it is sweeping. Thus blocks that are determined to be free are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7981
// indeed free. There is however one additional complication:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7982
// blocks that have been allocated since the final checkpoint and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7983
// mark, will not have been marked and so would be treated as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7984
// unreachable and swept up. To prevent this, the allocator marks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7985
// the bit map when allocating during the sweep phase. This leads,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7986
// however, to a further complication -- objects may have been allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7987
// but not yet initialized -- in the sense that the header isn't yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7988
// installed. The sweeper can not then determine the size of the block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7989
// in order to skip over it. To deal with this case, we use a technique
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7990
// (due to Printezis) to encode such uninitialized block sizes in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7991
// bit map. Since the bit map uses a bit per every HeapWord, but the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7992
// CMS generation has a minimum object size of 3 HeapWords, it follows
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7993
// that "normal marks" won't be adjacent in the bit map (there will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7994
// always be at least two 0 bits between successive 1 bits). We make use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7995
// of these "unused" bits to represent uninitialized blocks -- the bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7996
// corresponding to the start of the uninitialized object and the next
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7997
// bit are both set. Finally, a 1 bit marks the end of the object that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7998
// started with the two consecutive 1 bits to indicate its potentially
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7999
// uninitialized state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8001
size_t SweepClosure::do_blk_careful(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8002
  FreeChunk* fc = (FreeChunk*)addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8003
  size_t res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8004
6262
439992021ba8 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 6258
diff changeset
  8005
  // Check if we are done sweeping. Below we check "addr >= _limit" rather
439992021ba8 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 6258
diff changeset
  8006
  // than "addr == _limit" because although _limit was a block boundary when
439992021ba8 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 6258
diff changeset
  8007
  // we started the sweep, it may no longer be one because heap expansion
439992021ba8 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 6258
diff changeset
  8008
  // may have caused us to coalesce the block ending at the address _limit
439992021ba8 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 6258
diff changeset
  8009
  // with a newly expanded chunk (this happens when _limit was set to the
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8010
  // previous _end of the space), so we may have stepped past _limit:
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8011
  // see the following Zeno-like trail of CRs 6977970, 7008136, 7042740.
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8012
  if (addr >= _limit) { // we have swept up to or past the limit: finish up
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8013
    assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8014
           "sweep _limit out of bounds");
6262
439992021ba8 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 6258
diff changeset
  8015
    assert(addr < _sp->end(), "addr out of bounds");
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8016
    // Flush any free range we might be holding as a single
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8017
    // coalesced chunk to the appropriate free list.
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8018
    if (inFreeRange()) {
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8019
      assert(freeFinger() >= _sp->bottom() && freeFinger() < _limit,
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8020
             err_msg("freeFinger() " PTR_FORMAT" is out-of-bounds", freeFinger()));
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8021
      flush_cur_free_chunk(freeFinger(),
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8022
                           pointer_delta(addr, freeFinger()));
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8023
      if (CMSTraceSweeper) {
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8024
        gclog_or_tty->print("Sweep: last chunk: ");
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8025
        gclog_or_tty->print("put_free_blk 0x%x ("SIZE_FORMAT") "
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8026
                   "[coalesced:"SIZE_FORMAT"]\n",
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8027
                   freeFinger(), pointer_delta(addr, freeFinger()),
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8028
                   lastFreeRangeCoalesced());
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8029
      }
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8030
    }
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8031
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8032
    // help the iterator loop finish
6262
439992021ba8 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 6258
diff changeset
  8033
    return pointer_delta(_sp->end(), addr);
439992021ba8 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 6258
diff changeset
  8034
  }
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8035
6262
439992021ba8 6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
ysr
parents: 6258
diff changeset
  8036
  assert(addr < _limit, "sweep invariant");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8037
  // check if we should yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8038
  do_yield_check(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8039
  if (fc->isFree()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8040
    // Chunk that is already free
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8041
    res = fc->size();
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8042
    do_already_free_chunk(fc);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8043
    debug_only(_sp->verifyFreeLists());
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8044
    // If we flush the chunk at hand in lookahead_and_flush()
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8045
    // and it's coalesced with a preceding chunk, then the
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8046
    // process of "mangling" the payload of the coalesced block
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8047
    // will cause erasure of the size information from the
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8048
    // (erstwhile) header of all the coalesced blocks but the
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8049
    // first, so the first disjunct in the assert will not hold
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8050
    // in that specific case (in which case the second disjunct
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8051
    // will hold).
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8052
    assert(res == fc->size() || ((HeapWord*)fc) + res >= _limit,
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8053
           "Otherwise the size info doesn't change at this step");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8054
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8055
      _numObjectsAlreadyFree++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8056
      _numWordsAlreadyFree += res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8057
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8058
    NOT_PRODUCT(_last_fc = fc;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8059
  } else if (!_bitMap->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8060
    // Chunk is fresh garbage
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8061
    res = do_garbage_chunk(fc);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8062
    debug_only(_sp->verifyFreeLists());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8063
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8064
      _numObjectsFreed++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8065
      _numWordsFreed += res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8066
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8067
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8068
    // Chunk that is alive.
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8069
    res = do_live_chunk(fc);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8070
    debug_only(_sp->verifyFreeLists());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8071
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8072
        _numObjectsLive++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8073
        _numWordsLive += res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8074
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8075
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8076
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8077
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8078
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8079
// For the smart allocation, record following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8080
//  split deaths - a free chunk is removed from its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8081
//      it is being split into two or more chunks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8082
//  split birth - a free chunk is being added to its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8083
//      a larger free chunk has been split and resulted in this free chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8084
//  coal death - a free chunk is being removed from its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8085
//      it is being coalesced into a large free chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8086
//  coal birth - a free chunk is being added to its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8087
//      it was created when two or more free chunks where coalesced into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8088
//      this free chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8089
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8090
// These statistics are used to determine the desired number of free
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8091
// chunks of a given size.  The desired number is chosen to be relative
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8092
// to the end of a CMS sweep.  The desired number at the end of a sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8093
// is the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8094
//      count-at-end-of-previous-sweep (an amount that was enough)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8095
//              - count-at-beginning-of-current-sweep  (the excess)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8096
//              + split-births  (gains in this size during interval)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8097
//              - split-deaths  (demands on this size during interval)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8098
// where the interval is from the end of one sweep to the end of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8099
// next.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8100
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8101
// When sweeping the sweeper maintains an accumulated chunk which is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8102
// the chunk that is made up of chunks that have been coalesced.  That
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8103
// will be termed the left-hand chunk.  A new chunk of garbage that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8104
// is being considered for coalescing will be referred to as the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8105
// right-hand chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8106
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8107
// When making a decision on whether to coalesce a right-hand chunk with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8108
// the current left-hand chunk, the current count vs. the desired count
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8109
// of the left-hand chunk is considered.  Also if the right-hand chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8110
// is near the large chunk at the end of the heap (see
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8111
// ConcurrentMarkSweepGeneration::isNearLargestChunk()), then the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8112
// left-hand chunk is coalesced.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8113
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8114
// When making a decision about whether to split a chunk, the desired count
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8115
// vs. the current count of the candidate to be split is also considered.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8116
// If the candidate is underpopulated (currently fewer chunks than desired)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8117
// a chunk of an overpopulated (currently more chunks than desired) size may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8118
// be chosen.  The "hint" associated with a free list, if non-null, points
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8119
// to a free list which may be overpopulated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8120
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8121
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8122
void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8123
  const size_t size = fc->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8124
  // Chunks that cannot be coalesced are not in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8125
  // free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8126
  if (CMSTestInFreeList && !fc->cantCoalesce()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8127
    assert(_sp->verifyChunkInFreeLists(fc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8128
      "free chunk should be in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8129
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8130
  // a chunk that is already free, should not have been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8131
  // marked in the bit map
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8132
  HeapWord* const addr = (HeapWord*) fc;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8133
  assert(!_bitMap->isMarked(addr), "free chunk should be unmarked");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8134
  // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8135
  // addr and purported end of this block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8136
  _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8137
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8138
  // Some chunks cannot be coalesced under any circumstances.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8139
  // See the definition of cantCoalesce().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8140
  if (!fc->cantCoalesce()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8141
    // This chunk can potentially be coalesced.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8142
    if (_sp->adaptive_freelists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8143
      // All the work is done in
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8144
      do_post_free_or_garbage_chunk(fc, size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8145
    } else {  // Not adaptive free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8146
      // this is a free chunk that can potentially be coalesced by the sweeper;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8147
      if (!inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8148
        // if the next chunk is a free block that can't be coalesced
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8149
        // it doesn't make sense to remove this chunk from the free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8150
        FreeChunk* nextChunk = (FreeChunk*)(addr + size);
7907
2cd00061953b 7011940: iCMS: SIGSEGV in SweepClosure::do_already_free_chunk(FreeChunk*)+0x360
ysr
parents: 7903
diff changeset
  8151
        assert((HeapWord*)nextChunk <= _sp->end(), "Chunk size out of bounds?");
2cd00061953b 7011940: iCMS: SIGSEGV in SweepClosure::do_already_free_chunk(FreeChunk*)+0x360
ysr
parents: 7903
diff changeset
  8152
        if ((HeapWord*)nextChunk < _sp->end() &&     // There is another free chunk to the right ...
2cd00061953b 7011940: iCMS: SIGSEGV in SweepClosure::do_already_free_chunk(FreeChunk*)+0x360
ysr
parents: 7903
diff changeset
  8153
            nextChunk->isFree()               &&     // ... which is free...
2cd00061953b 7011940: iCMS: SIGSEGV in SweepClosure::do_already_free_chunk(FreeChunk*)+0x360
ysr
parents: 7903
diff changeset
  8154
            nextChunk->cantCoalesce()) {             // ... but can't be coalesced
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8155
          // nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8156
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8157
          // Potentially the start of a new free range:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8158
          // Don't eagerly remove it from the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8159
          // No need to remove it if it will just be put
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8160
          // back again.  (Also from a pragmatic point of view
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8161
          // if it is a free block in a region that is beyond
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8162
          // any allocated blocks, an assertion will fail)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8163
          // Remember the start of a free run.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8164
          initialize_free_range(addr, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8165
          // end - can coalesce with next chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8166
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8167
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8168
        // the midst of a free range, we are coalescing
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8169
        print_free_block_coalesced(fc);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8170
        if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8171
          gclog_or_tty->print("  -- pick up free block 0x%x (%d)\n", fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8172
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8173
        // remove it from the free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8174
        _sp->removeFreeChunkFromFreeLists(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8175
        set_lastFreeRangeCoalesced(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8176
        // If the chunk is being coalesced and the current free range is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8177
        // in the free lists, remove the current free range so that it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8178
        // will be returned to the free lists in its entirety - all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8179
        // the coalesced pieces included.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8180
        if (freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8181
          FreeChunk* ffc = (FreeChunk*) freeFinger();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8182
          assert(ffc->size() == pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8183
            "Size of free range is inconsistent with chunk size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8184
          if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8185
            assert(_sp->verifyChunkInFreeLists(ffc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8186
              "free range is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8187
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8188
          _sp->removeFreeChunkFromFreeLists(ffc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8189
          set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8190
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8191
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8192
    }
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8193
    // Note that if the chunk is not coalescable (the else arm
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8194
    // below), we unconditionally flush, without needing to do
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8195
    // a "lookahead," as we do below.
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8196
    if (inFreeRange()) lookahead_and_flush(fc, size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8197
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8198
    // Code path common to both original and adaptive free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8199
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8200
    // cant coalesce with previous block; this should be treated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8201
    // as the end of a free run if any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8202
    if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8203
      // we kicked some butt; time to pick up the garbage
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8204
      assert(freeFinger() < addr, "freeFinger points too high");
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8205
      flush_cur_free_chunk(freeFinger(), pointer_delta(addr, freeFinger()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8206
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8207
    // else, nothing to do, just continue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8208
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8209
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8210
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8211
size_t SweepClosure::do_garbage_chunk(FreeChunk* fc) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8212
  // This is a chunk of garbage.  It is not in any free list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8213
  // Add it to a free list or let it possibly be coalesced into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8214
  // a larger chunk.
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8215
  HeapWord* const addr = (HeapWord*) fc;
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8216
  const size_t size = CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8217
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8218
  if (_sp->adaptive_freelists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8219
    // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8220
    // addr and purported end of just dead object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8221
    _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8222
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8223
    do_post_free_or_garbage_chunk(fc, size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8224
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8225
    if (!inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8226
      // start of a new free range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8227
      assert(size > 0, "A free range should have a size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8228
      initialize_free_range(addr, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8229
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8230
      // this will be swept up when we hit the end of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8231
      // free range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8232
      if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8233
        gclog_or_tty->print("  -- pick up garbage 0x%x (%d) \n", fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8234
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8235
      // If the chunk is being coalesced and the current free range is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8236
      // in the free lists, remove the current free range so that it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8237
      // will be returned to the free lists in its entirety - all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8238
      // the coalesced pieces included.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8239
      if (freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8240
        FreeChunk* ffc = (FreeChunk*)freeFinger();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8241
        assert(ffc->size() == pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8242
          "Size of free range is inconsistent with chunk size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8243
        if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8244
          assert(_sp->verifyChunkInFreeLists(ffc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8245
            "free range is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8246
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8247
        _sp->removeFreeChunkFromFreeLists(ffc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8248
        set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8249
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8250
      set_lastFreeRangeCoalesced(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8251
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8252
    // this will be swept up when we hit the end of the free range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8253
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8254
    // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8255
    // addr and purported end of just dead object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8256
    _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8257
  }
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8258
  assert(_limit >= addr + size,
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8259
         "A freshly garbage chunk can't possibly straddle over _limit");
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8260
  if (inFreeRange()) lookahead_and_flush(fc, size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8261
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8262
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8263
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8264
size_t SweepClosure::do_live_chunk(FreeChunk* fc) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8265
  HeapWord* addr = (HeapWord*) fc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8266
  // The sweeper has just found a live object. Return any accumulated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8267
  // left hand chunk to the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8268
  if (inFreeRange()) {
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8269
    assert(freeFinger() < addr, "freeFinger points too high");
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8270
    flush_cur_free_chunk(freeFinger(), pointer_delta(addr, freeFinger()));
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8271
  }
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8272
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8273
  // This object is live: we'd normally expect this to be
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8274
  // an oop, and like to assert the following:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8275
  // assert(oop(addr)->is_oop(), "live block should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8276
  // However, as we commented above, this may be an object whose
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8277
  // header hasn't yet been initialized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8278
  size_t size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8279
  assert(_bitMap->isMarked(addr), "Tautology for this control point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8280
  if (_bitMap->isMarked(addr + 1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8281
    // Determine the size from the bit map, rather than trying to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8282
    // compute it from the object header.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8283
    HeapWord* nextOneAddr = _bitMap->getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8284
    size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8285
    assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8286
           "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8287
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8288
#ifdef DEBUG
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  8289
      if (oop(addr)->klass_or_null() != NULL &&
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  8290
          (   !_collector->should_unload_classes()
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8291
           || (oop(addr)->is_parsable()) &&
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8292
               oop(addr)->is_conc_safe())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8293
        // Ignore mark word because we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8294
        assert(oop(addr)->is_oop(true), "live block should be an oop");
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8295
        // is_conc_safe is checked before performing this assertion
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8296
        // because an object that is not is_conc_safe may yet have
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8297
        // the return from size() correct.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8298
        assert(size ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8299
               CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8300
               "P-mark and computed size do not agree");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8301
      }
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8302
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8303
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8304
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8305
    // This should be an initialized object that's alive.
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  8306
    assert(oop(addr)->klass_or_null() != NULL &&
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  8307
           (!_collector->should_unload_classes()
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8308
            || oop(addr)->is_parsable()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8309
           "Should be an initialized object");
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8310
    // Note that there are objects used during class redefinition,
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8311
    // e.g. merge_cp in VM_RedefineClasses::merge_cp_and_rewrite(),
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8312
    // which are discarded with their is_conc_safe state still
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8313
    // false.  These object may be floating garbage so may be
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8314
    // seen here.  If they are floating garbage their size
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8315
    // should be attainable from their klass.  Do not that
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8316
    // is_conc_safe() is true for oop(addr).
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8317
    // Ignore mark word because we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8318
    assert(oop(addr)->is_oop(true), "live block should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8319
    // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8320
    // addr and purported end of this block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8321
    size = CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8322
    assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8323
    assert(!_bitMap->isMarked(addr+1), "Tautology for this control point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8324
    DEBUG_ONLY(_bitMap->verifyNoOneBitsInRange(addr+2, addr+size);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8325
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8326
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8327
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8328
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8329
void SweepClosure::do_post_free_or_garbage_chunk(FreeChunk* fc,
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8330
                                                 size_t chunkSize) {
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8331
  // do_post_free_or_garbage_chunk() should only be called in the case
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8332
  // of the adaptive free list allocator.
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8333
  const bool fcInFreeLists = fc->isFree();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8334
  assert(_sp->adaptive_freelists(), "Should only be used in this case.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8335
  assert((HeapWord*)fc <= _limit, "sweep invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8336
  if (CMSTestInFreeList && fcInFreeLists) {
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8337
    assert(_sp->verifyChunkInFreeLists(fc), "free chunk is not in free lists");
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8338
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8339
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8340
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8341
    gclog_or_tty->print_cr("  -- pick up another chunk at 0x%x (%d)", fc, chunkSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8342
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8343
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8344
  HeapWord* const fc_addr = (HeapWord*) fc;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8345
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8346
  bool coalesce;
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8347
  const size_t left  = pointer_delta(fc_addr, freeFinger());
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8348
  const size_t right = chunkSize;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8349
  switch (FLSCoalescePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8350
    // numeric value forms a coalition aggressiveness metric
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8351
    case 0:  { // never coalesce
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8352
      coalesce = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8353
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8354
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8355
    case 1: { // coalesce if left & right chunks on overpopulated lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8356
      coalesce = _sp->coalOverPopulated(left) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8357
                 _sp->coalOverPopulated(right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8358
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8359
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8360
    case 2: { // coalesce if left chunk on overpopulated list (default)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8361
      coalesce = _sp->coalOverPopulated(left);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8362
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8363
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8364
    case 3: { // coalesce if left OR right chunk on overpopulated list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8365
      coalesce = _sp->coalOverPopulated(left) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8366
                 _sp->coalOverPopulated(right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8367
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8368
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8369
    case 4: { // always coalesce
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8370
      coalesce = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8371
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8372
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8373
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8374
     ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8375
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8376
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8377
  // Should the current free range be coalesced?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8378
  // If the chunk is in a free range and either we decided to coalesce above
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8379
  // or the chunk is near the large block at the end of the heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8380
  // (isNearLargestChunk() returns true), then coalesce this chunk.
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8381
  const bool doCoalesce = inFreeRange()
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8382
                          && (coalesce || _g->isNearLargestChunk(fc_addr));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8383
  if (doCoalesce) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8384
    // Coalesce the current free range on the left with the new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8385
    // chunk on the right.  If either is on a free list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8386
    // it must be removed from the list and stashed in the closure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8387
    if (freeRangeInFreeLists()) {
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8388
      FreeChunk* const ffc = (FreeChunk*)freeFinger();
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8389
      assert(ffc->size() == pointer_delta(fc_addr, freeFinger()),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8390
        "Size of free range is inconsistent with chunk size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8391
      if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8392
        assert(_sp->verifyChunkInFreeLists(ffc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8393
          "Chunk is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8394
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8395
      _sp->coalDeath(ffc->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8396
      _sp->removeFreeChunkFromFreeLists(ffc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8397
      set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8398
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8399
    if (fcInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8400
      _sp->coalDeath(chunkSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8401
      assert(fc->size() == chunkSize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8402
        "The chunk has the wrong size or is not in the free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8403
      _sp->removeFreeChunkFromFreeLists(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8404
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8405
    set_lastFreeRangeCoalesced(true);
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8406
    print_free_block_coalesced(fc);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8407
  } else {  // not in a free range and/or should not coalesce
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8408
    // Return the current free range and start a new one.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8409
    if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8410
      // In a free range but cannot coalesce with the right hand chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8411
      // Put the current free range into the free lists.
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8412
      flush_cur_free_chunk(freeFinger(),
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8413
                           pointer_delta(fc_addr, freeFinger()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8414
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8415
    // Set up for new free range.  Pass along whether the right hand
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8416
    // chunk is in the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8417
    initialize_free_range((HeapWord*)fc, fcInFreeLists);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8418
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8419
}
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8420
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8421
// Lookahead flush:
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8422
// If we are tracking a free range, and this is the last chunk that
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8423
// we'll look at because its end crosses past _limit, we'll preemptively
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8424
// flush it along with any free range we may be holding on to. Note that
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8425
// this can be the case only for an already free or freshly garbage
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8426
// chunk. If this block is an object, it can never straddle
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8427
// over _limit. The "straddling" occurs when _limit is set at
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8428
// the previous end of the space when this cycle started, and
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8429
// a subsequent heap expansion caused the previously co-terminal
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8430
// free block to be coalesced with the newly expanded portion,
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8431
// thus rendering _limit a non-block-boundary making it dangerous
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8432
// for the sweeper to step over and examine.
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8433
void SweepClosure::lookahead_and_flush(FreeChunk* fc, size_t chunk_size) {
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8434
  assert(inFreeRange(), "Should only be called if currently in a free range.");
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8435
  HeapWord* const eob = ((HeapWord*)fc) + chunk_size;
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8436
  assert(_sp->used_region().contains(eob - 1),
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8437
         err_msg("eob = " PTR_FORMAT " out of bounds wrt _sp = [" PTR_FORMAT "," PTR_FORMAT ")"
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8438
                 " when examining fc = " PTR_FORMAT "(" SIZE_FORMAT ")",
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8439
                 _limit, _sp->bottom(), _sp->end(), fc, chunk_size));
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8440
  if (eob >= _limit) {
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8441
    assert(eob == _limit || fc->isFree(), "Only a free chunk should allow us to cross over the limit");
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8442
    if (CMSTraceSweeper) {
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8443
      gclog_or_tty->print_cr("_limit " PTR_FORMAT " reached or crossed by block "
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8444
                             "[" PTR_FORMAT "," PTR_FORMAT ") in space "
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8445
                             "[" PTR_FORMAT "," PTR_FORMAT ")",
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8446
                             _limit, fc, eob, _sp->bottom(), _sp->end());
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8447
    }
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8448
    // Return the storage we are tracking back into the free lists.
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8449
    if (CMSTraceSweeper) {
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8450
      gclog_or_tty->print_cr("Flushing ... ");
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8451
    }
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8452
    assert(freeFinger() < eob, "Error");
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8453
    flush_cur_free_chunk( freeFinger(), pointer_delta(eob, freeFinger()));
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8454
  }
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8455
}
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8456
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8457
void SweepClosure::flush_cur_free_chunk(HeapWord* chunk, size_t size) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8458
  assert(inFreeRange(), "Should only be called if currently in a free range.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8459
  assert(size > 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8460
    "A zero sized chunk cannot be added to the free lists.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8461
  if (!freeRangeInFreeLists()) {
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8462
    if (CMSTestInFreeList) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8463
      FreeChunk* fc = (FreeChunk*) chunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8464
      fc->setSize(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8465
      assert(!_sp->verifyChunkInFreeLists(fc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8466
        "chunk should not be in free lists yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8467
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8468
    if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8469
      gclog_or_tty->print_cr(" -- add free block 0x%x (%d) to free lists",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8470
                    chunk, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8471
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8472
    // A new free range is going to be starting.  The current
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8473
    // free range has not been added to the free lists yet or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8474
    // was removed so add it back.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8475
    // If the current free range was coalesced, then the death
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8476
    // of the free range was recorded.  Record a birth now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8477
    if (lastFreeRangeCoalesced()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8478
      _sp->coalBirth(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8479
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8480
    _sp->addChunkAndRepairOffsetTable(chunk, size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8481
            lastFreeRangeCoalesced());
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8482
  } else if (CMSTraceSweeper) {
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8483
    gclog_or_tty->print_cr("Already in free list: nothing to flush");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8484
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8485
  set_inFreeRange(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8486
  set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8487
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8488
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8489
// We take a break if we've been at this for a while,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8490
// so as to avoid monopolizing the locks involved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8491
void SweepClosure::do_yield_work(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8492
  // Return current free chunk being used for coalescing (if any)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8493
  // to the appropriate freelist.  After yielding, the next
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8494
  // free block encountered will start a coalescing range of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8495
  // free blocks.  If the next free block is adjacent to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8496
  // chunk just flushed, they will need to wait for the next
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8497
  // sweep to be coalesced.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8498
  if (inFreeRange()) {
7903
c694e52ff9cb 7008136: CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
ysr
parents: 7419
diff changeset
  8499
    flush_cur_free_chunk(freeFinger(), pointer_delta(addr, freeFinger()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8500
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8501
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8502
  // First give up the locks, then yield, then re-lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8503
  // We should probably use a constructor/destructor idiom to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8504
  // do this unlock/lock or modify the MutexUnlocker class to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8505
  // serve our purpose. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8506
  assert_lock_strong(_bitMap->lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8507
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8508
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8509
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8510
  _bitMap->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8511
  _freelistLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8512
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8513
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8514
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8515
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8516
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8517
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8518
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8519
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8520
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8521
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8522
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8523
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8524
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8525
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8526
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8527
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8528
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8529
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8530
  _freelistLock->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8531
  _bitMap->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8532
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8533
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8534
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8535
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8536
// This is actually very useful in a product build if it can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8537
// be called from the debugger.  Compile it into the product
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8538
// as needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8539
bool debug_verifyChunkInFreeLists(FreeChunk* fc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8540
  return debug_cms_space->verifyChunkInFreeLists(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8541
}
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8542
#endif
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8543
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8544
void SweepClosure::print_free_block_coalesced(FreeChunk* fc) const {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8545
  if (CMSTraceSweeper) {
9969
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8546
    gclog_or_tty->print_cr("Sweep:coal_free_blk " PTR_FORMAT " (" SIZE_FORMAT ")",
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8547
                           fc, fc->size());
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8548
  }
57932d7294a9 7042740: CMS: assert(n> q) failed: Looping at: ... blockOffsetTable.cpp:557
ysr
parents: 9623
diff changeset
  8549
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8550
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8551
// CMSIsAliveClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8552
bool CMSIsAliveClosure::do_object_b(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8553
  HeapWord* addr = (HeapWord*)obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8554
  return addr != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8555
         (!_span.contains(addr) || _bit_map->isMarked(addr));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8556
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8557
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8558
CMSKeepAliveClosure::CMSKeepAliveClosure( CMSCollector* collector,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8559
                      MemRegion span,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8560
                      CMSBitMap* bit_map, CMSMarkStack* mark_stack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8561
                      CMSMarkStack* revisit_stack, bool cpc):
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8562
  KlassRememberingOopClosure(collector, NULL, revisit_stack),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8563
  _span(span),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8564
  _bit_map(bit_map),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8565
  _mark_stack(mark_stack),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8566
  _concurrent_precleaning(cpc) {
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8567
  assert(!_span.is_empty(), "Empty span could spell trouble");
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8568
}
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8569
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8570
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8571
// CMSKeepAliveClosure: the serial version
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8572
void CMSKeepAliveClosure::do_oop(oop obj) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8573
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8574
  if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8575
      !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8576
    _bit_map->mark(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8577
    bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8578
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8579
      if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8580
          _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8581
        // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8582
        simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8583
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8584
    )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8585
    if (simulate_overflow || !_mark_stack->push(obj)) {
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8586
      if (_concurrent_precleaning) {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8587
        // We dirty the overflown object and let the remark
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8588
        // phase deal with it.
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8589
        assert(_collector->overflow_list_is_empty(), "Error");
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8590
        // In the case of object arrays, we need to dirty all of
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8591
        // the cards that the object spans. No locking or atomics
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8592
        // are needed since no one else can be mutating the mod union
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8593
        // table.
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8594
        if (obj->is_objArray()) {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8595
          size_t sz = obj->size();
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8596
          HeapWord* end_card_addr =
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8597
            (HeapWord*)round_to((intptr_t)(addr+sz), CardTableModRefBS::card_size);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8598
          MemRegion redirty_range = MemRegion(addr, end_card_addr);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8599
          assert(!redirty_range.is_empty(), "Arithmetical tautology");
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8600
          _collector->_modUnionTable.mark_range(redirty_range);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8601
        } else {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8602
          _collector->_modUnionTable.mark(addr);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8603
        }
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8604
        _collector->_ser_kac_preclean_ovflw++;
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8605
      } else {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8606
        _collector->push_on_overflow_list(obj);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8607
        _collector->_ser_kac_ovflw++;
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8608
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8609
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8610
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8611
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8612
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8613
void CMSKeepAliveClosure::do_oop(oop* p)       { CMSKeepAliveClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8614
void CMSKeepAliveClosure::do_oop(narrowOop* p) { CMSKeepAliveClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8615
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8616
// CMSParKeepAliveClosure: a parallel version of the above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8617
// The work queues are private to each closure (thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8618
// but (may be) available for stealing by other threads.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8619
void CMSParKeepAliveClosure::do_oop(oop obj) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8620
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8621
  if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8622
      !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8623
    // In general, during recursive tracing, several threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8624
    // may be concurrently getting here; the first one to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8625
    // "tag" it, claims it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8626
    if (_bit_map->par_mark(addr)) {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8627
      bool res = _work_queue->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8628
      assert(res, "Low water mark should be much less than capacity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8629
      // Do a recursive trim in the hope that this will keep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8630
      // stack usage lower, but leave some oops for potential stealers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8631
      trim_queue(_low_water_mark);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8632
    } // Else, another thread got there first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8633
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8634
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8635
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8636
void CMSParKeepAliveClosure::do_oop(oop* p)       { CMSParKeepAliveClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8637
void CMSParKeepAliveClosure::do_oop(narrowOop* p) { CMSParKeepAliveClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8638
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8639
void CMSParKeepAliveClosure::trim_queue(uint max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8640
  while (_work_queue->size() > max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8641
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8642
    if (_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8643
      assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8644
      assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8645
             "no white objects on this stack!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8646
      assert(_span.contains((HeapWord*)new_oop), "Out of bounds oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8647
      // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8648
      // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8649
      new_oop->oop_iterate(&_mark_and_push);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8650
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8651
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8652
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8653
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8654
CMSInnerParMarkAndPushClosure::CMSInnerParMarkAndPushClosure(
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8655
                                CMSCollector* collector,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8656
                                MemRegion span, CMSBitMap* bit_map,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8657
                                CMSMarkStack* revisit_stack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8658
                                OopTaskQueue* work_queue):
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8659
  Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8660
  _span(span),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8661
  _bit_map(bit_map),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8662
  _work_queue(work_queue) { }
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8663
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8664
void CMSInnerParMarkAndPushClosure::do_oop(oop obj) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8665
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8666
  if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8667
      !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8668
    if (_bit_map->par_mark(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8669
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8670
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8671
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8672
            _collector->par_simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8673
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8674
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8675
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8676
      )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8677
      if (simulate_overflow || !_work_queue->push(obj)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8678
        _collector->par_push_on_overflow_list(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8679
        _collector->_par_kac_ovflw++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8680
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8681
    } // Else another thread got there already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8682
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8683
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8684
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8685
void CMSInnerParMarkAndPushClosure::do_oop(oop* p)       { CMSInnerParMarkAndPushClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8686
void CMSInnerParMarkAndPushClosure::do_oop(narrowOop* p) { CMSInnerParMarkAndPushClosure::do_oop_work(p); }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8687
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8688
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8689
//  CMSExpansionCause                /////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8690
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8691
const char* CMSExpansionCause::to_string(CMSExpansionCause::Cause cause) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8692
  switch (cause) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8693
    case _no_expansion:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8694
      return "No expansion";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8695
    case _satisfy_free_ratio:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8696
      return "Free ratio";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8697
    case _satisfy_promotion:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8698
      return "Satisfy promotion";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8699
    case _satisfy_allocation:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8700
      return "allocation";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8701
    case _allocate_par_lab:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8702
      return "Par LAB";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8703
    case _allocate_par_spooling_space:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8704
      return "Par Spooling Space";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8705
    case _adaptive_size_policy:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8706
      return "Ergonomics";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8707
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8708
      return "unknown";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8709
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8710
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8711
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8712
void CMSDrainMarkingStackClosure::do_void() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8713
  // the max number to take from overflow list at a time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8714
  const size_t num = _mark_stack->capacity()/4;
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8715
  assert(!_concurrent_precleaning || _collector->overflow_list_is_empty(),
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8716
         "Overflow list should be NULL during concurrent phases");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8717
  while (!_mark_stack->isEmpty() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8718
         // if stack is empty, check the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8719
         _collector->take_from_overflow_list(num, _mark_stack)) {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8720
    oop obj = _mark_stack->pop();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8721
    HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8722
    assert(_span.contains(addr), "Should be within span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8723
    assert(_bit_map->isMarked(addr), "Should be marked");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8724
    assert(obj->is_oop(), "Should be an oop");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8725
    obj->oop_iterate(_keep_alive);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8726
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8727
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8728
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8729
void CMSParDrainMarkingStackClosure::do_void() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8730
  // drain queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8731
  trim_queue(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8732
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8733
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8734
// Trim our work_queue so its length is below max at return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8735
void CMSParDrainMarkingStackClosure::trim_queue(uint max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8736
  while (_work_queue->size() > max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8737
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8738
    if (_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8739
      assert(new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8740
      assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8741
             "no white objects on this stack!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8742
      assert(_span.contains((HeapWord*)new_oop), "Out of bounds oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8743
      // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8744
      // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8745
      new_oop->oop_iterate(&_mark_and_push);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8746
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8747
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8748
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8749
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8750
////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8751
// Support for Marking Stack Overflow list handling and related code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8752
////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8753
// Much of the following code is similar in shape and spirit to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8754
// code used in ParNewGC. We should try and share that code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8755
// as much as possible in the future.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8756
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8757
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8758
// Debugging support for CMSStackOverflowALot
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8759
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8760
// It's OK to call this multi-threaded;  the worst thing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8761
// that can happen is that we'll get a bunch of closely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8762
// spaced simulated oveflows, but that's OK, in fact
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8763
// probably good as it would exercise the overflow code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8764
// under contention.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8765
bool CMSCollector::simulate_overflow() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8766
  if (_overflow_counter-- <= 0) { // just being defensive
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8767
    _overflow_counter = CMSMarkStackOverflowInterval;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8768
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8769
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8770
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8771
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8772
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8773
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8774
bool CMSCollector::par_simulate_overflow() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8775
  return simulate_overflow();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8776
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8777
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8778
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8779
// Single-threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8780
bool CMSCollector::take_from_overflow_list(size_t num, CMSMarkStack* stack) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8781
  assert(stack->isEmpty(), "Expected precondition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8782
  assert(stack->capacity() > num, "Shouldn't bite more than can chew");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8783
  size_t i = num;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8784
  oop  cur = _overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8785
  const markOop proto = markOopDesc::prototype();
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8786
  NOT_PRODUCT(ssize_t n = 0;)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8787
  for (oop next; i > 0 && cur != NULL; cur = next, i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8788
    next = oop(cur->mark());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8789
    cur->set_mark(proto);   // until proven otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8790
    assert(cur->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8791
    bool res = stack->push(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8792
    assert(res, "Bit off more than can chew?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8793
    NOT_PRODUCT(n++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8794
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8795
  _overflow_list = cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8796
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8797
  assert(_num_par_pushes >= n, "Too many pops?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8798
  _num_par_pushes -=n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8799
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8800
  return !stack->isEmpty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8801
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8802
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8803
#define BUSY  (oop(0x1aff1aff))
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8804
// (MT-safe) Get a prefix of at most "num" from the list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8805
// The overflow list is chained through the mark word of
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8806
// each object in the list. We fetch the entire list,
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8807
// break off a prefix of the right size and return the
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8808
// remainder. If other threads try to take objects from
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8809
// the overflow list at that time, they will wait for
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8810
// some time to see if data becomes available. If (and
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8811
// only if) another thread places one or more object(s)
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8812
// on the global list before we have returned the suffix
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8813
// to the global list, we will walk down our local list
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8814
// to find its end and append the global list to
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8815
// our suffix before returning it. This suffix walk can
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8816
// prove to be expensive (quadratic in the amount of traffic)
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8817
// when there are many objects in the overflow list and
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8818
// there is much producer-consumer contention on the list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8819
// *NOTE*: The overflow list manipulation code here and
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8820
// in ParNewGeneration:: are very similar in shape,
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8821
// except that in the ParNew case we use the old (from/eden)
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8822
// copy of the object to thread the list via its klass word.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8823
// Because of the common code, if you make any changes in
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8824
// the code below, please check the ParNew version to see if
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8825
// similar changes might be needed.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8826
// CR 6797058 has been filed to consolidate the common code.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8827
bool CMSCollector::par_take_from_overflow_list(size_t num,
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  8828
                                               OopTaskQueue* work_q,
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  8829
                                               int no_of_gc_threads) {
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8830
  assert(work_q->size() == 0, "First empty local work queue");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8831
  assert(num < work_q->max_elems(), "Can't bite more than we can chew");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8832
  if (_overflow_list == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8833
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8834
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8835
  // Grab the entire list; we'll put back a suffix
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8836
  oop prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8837
  Thread* tid = Thread::current();
6759
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  8838
  // Before "no_of_gc_threads" was introduced CMSOverflowSpinCount was
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  8839
  // set to ParallelGCThreads.
67b1a69ef5aa 6984287: Regularize how GC parallel workers are specified.
jmasa
parents: 6447
diff changeset
  8840
  size_t CMSOverflowSpinCount = (size_t) no_of_gc_threads; // was ParallelGCThreads;
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8841
  size_t sleep_time_millis = MAX2((size_t)1, num/100);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8842
  // If the list is busy, we spin for a short while,
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8843
  // sleeping between attempts to get the list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8844
  for (size_t spin = 0; prefix == BUSY && spin < CMSOverflowSpinCount; spin++) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8845
    os::sleep(tid, sleep_time_millis, false);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8846
    if (_overflow_list == NULL) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8847
      // Nothing left to take
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8848
      return false;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8849
    } else if (_overflow_list != BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8850
      // Try and grab the prefix
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8851
      prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8852
    }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8853
  }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8854
  // If the list was found to be empty, or we spun long
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8855
  // enough, we give up and return empty-handed. If we leave
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8856
  // the list in the BUSY state below, it must be the case that
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8857
  // some other thread holds the overflow list and will set it
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8858
  // to a non-BUSY state in the future.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8859
  if (prefix == NULL || prefix == BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8860
     // Nothing to take or waited long enough
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8861
     if (prefix == NULL) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8862
       // Write back the NULL in case we overwrote it with BUSY above
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8863
       // and it is still the same value.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8864
       (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8865
     }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8866
     return false;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8867
  }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8868
  assert(prefix != NULL && prefix != BUSY, "Error");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8869
  size_t i = num;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8870
  oop cur = prefix;
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8871
  // Walk down the first "num" objects, unless we reach the end.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8872
  for (; i > 1 && cur->mark() != NULL; cur = oop(cur->mark()), i--);
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8873
  if (cur->mark() == NULL) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8874
    // We have "num" or fewer elements in the list, so there
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8875
    // is nothing to return to the global list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8876
    // Write back the NULL in lieu of the BUSY we wrote
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8877
    // above, if it is still the same value.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8878
    if (_overflow_list == BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8879
      (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8880
    }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8881
  } else {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8882
    // Chop off the suffix and rerturn it to the global list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8883
    assert(cur->mark() != BUSY, "Error");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8884
    oop suffix_head = cur->mark(); // suffix will be put back on global list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8885
    cur->set_mark(NULL);           // break off suffix
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8886
    // It's possible that the list is still in the empty(busy) state
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8887
    // we left it in a short while ago; in that case we may be
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8888
    // able to place back the suffix without incurring the cost
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8889
    // of a walk down the list.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8890
    oop observed_overflow_list = _overflow_list;
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8891
    oop cur_overflow_list = observed_overflow_list;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8892
    bool attached = false;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8893
    while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8894
      observed_overflow_list =
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8895
        (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8896
      if (cur_overflow_list == observed_overflow_list) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8897
        attached = true;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8898
        break;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8899
      } else cur_overflow_list = observed_overflow_list;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8900
    }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8901
    if (!attached) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8902
      // Too bad, someone else sneaked in (at least) an element; we'll need
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8903
      // to do a splice. Find tail of suffix so we can prepend suffix to global
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8904
      // list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8905
      for (cur = suffix_head; cur->mark() != NULL; cur = (oop)(cur->mark()));
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8906
      oop suffix_tail = cur;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8907
      assert(suffix_tail != NULL && suffix_tail->mark() == NULL,
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8908
             "Tautology");
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8909
      observed_overflow_list = _overflow_list;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8910
      do {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8911
        cur_overflow_list = observed_overflow_list;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8912
        if (cur_overflow_list != BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8913
          // Do the splice ...
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8914
          suffix_tail->set_mark(markOop(cur_overflow_list));
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8915
        } else { // cur_overflow_list == BUSY
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8916
          suffix_tail->set_mark(NULL);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8917
        }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8918
        // ... and try to place spliced list back on overflow_list ...
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8919
        observed_overflow_list =
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8920
          (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8921
      } while (cur_overflow_list != observed_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8922
      // ... until we have succeeded in doing so.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8923
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8924
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8925
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8926
  // Push the prefix elements on work_q
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8927
  assert(prefix != NULL, "control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8928
  const markOop proto = markOopDesc::prototype();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8929
  oop next;
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8930
  NOT_PRODUCT(ssize_t n = 0;)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8931
  for (cur = prefix; cur != NULL; cur = next) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8932
    next = oop(cur->mark());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8933
    cur->set_mark(proto);   // until proven otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8934
    assert(cur->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8935
    bool res = work_q->push(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8936
    assert(res, "Bit off more than we can chew?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8937
    NOT_PRODUCT(n++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8938
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8939
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8940
  assert(_num_par_pushes >= n, "Too many pops?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8941
  Atomic::add_ptr(-(intptr_t)n, &_num_par_pushes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8942
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8943
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8944
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8945
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8946
// Single-threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8947
void CMSCollector::push_on_overflow_list(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8948
  NOT_PRODUCT(_num_par_pushes++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8949
  assert(p->is_oop(), "Not an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8950
  preserve_mark_if_necessary(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8951
  p->set_mark((markOop)_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8952
  _overflow_list = p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8953
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8954
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8955
// Multi-threaded; use CAS to prepend to overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8956
void CMSCollector::par_push_on_overflow_list(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8957
  NOT_PRODUCT(Atomic::inc_ptr(&_num_par_pushes);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8958
  assert(p->is_oop(), "Not an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8959
  par_preserve_mark_if_necessary(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8960
  oop observed_overflow_list = _overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8961
  oop cur_overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8962
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8963
    cur_overflow_list = observed_overflow_list;
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8964
    if (cur_overflow_list != BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8965
      p->set_mark(markOop(cur_overflow_list));
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8966
    } else {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8967
      p->set_mark(NULL);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8968
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8969
    observed_overflow_list =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8970
      (oop) Atomic::cmpxchg_ptr(p, &_overflow_list, cur_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8971
  } while (cur_overflow_list != observed_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8972
}
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8973
#undef BUSY
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8974
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8975
// Single threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8976
// General Note on GrowableArray: pushes may silently fail
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8977
// because we are (temporarily) out of C-heap for expanding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8978
// the stack. The problem is quite ubiquitous and affects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8979
// a lot of code in the JVM. The prudent thing for GrowableArray
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8980
// to do (for now) is to exit with an error. However, that may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8981
// be too draconian in some cases because the caller may be
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8982
// able to recover without much harm. For such cases, we
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8983
// should probably introduce a "soft_push" method which returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8984
// an indication of success or failure with the assumption that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8985
// the caller may be able to recover from a failure; code in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8986
// the VM can then be changed, incrementally, to deal with such
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8987
// failures where possible, thus, incrementally hardening the VM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8988
// in such low resource situations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8989
void CMSCollector::preserve_mark_work(oop p, markOop m) {
6762
f8d1b560700e 6423256: GC stacks should use a better data structure
jcoomes
parents: 6759
diff changeset
  8990
  _preserved_oop_stack.push(p);
f8d1b560700e 6423256: GC stacks should use a better data structure
jcoomes
parents: 6759
diff changeset
  8991
  _preserved_mark_stack.push(m);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8992
  assert(m == p->mark(), "Mark word changed");
6762
f8d1b560700e 6423256: GC stacks should use a better data structure
jcoomes
parents: 6759
diff changeset
  8993
  assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8994
         "bijection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8995
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8996
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8997
// Single threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8998
void CMSCollector::preserve_mark_if_necessary(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8999
  markOop m = p->mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9000
  if (m->must_be_preserved(p)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9001
    preserve_mark_work(p, m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9002
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9003
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9004
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9005
void CMSCollector::par_preserve_mark_if_necessary(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9006
  markOop m = p->mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9007
  if (m->must_be_preserved(p)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9008
    MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9009
    // Even though we read the mark word without holding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9010
    // the lock, we are assured that it will not change
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9011
    // because we "own" this oop, so no other thread can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9012
    // be trying to push it on the overflow list; see
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9013
    // the assertion in preserve_mark_work() that checks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9014
    // that m == p->mark().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9015
    preserve_mark_work(p, m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9016
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9017
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9018
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9019
// We should be able to do this multi-threaded,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9020
// a chunk of stack being a task (this is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9021
// correct because each oop only ever appears
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9022
// once in the overflow list. However, it's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9023
// not very easy to completely overlap this with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9024
// other operations, so will generally not be done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9025
// until all work's been completed. Because we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9026
// expect the preserved oop stack (set) to be small,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9027
// it's probably fine to do this single-threaded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9028
// We can explore cleverer concurrent/overlapped/parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9029
// processing of preserved marks if we feel the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9030
// need for this in the future. Stack overflow should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9031
// be so rare in practice and, when it happens, its
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9032
// effect on performance so great that this will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9033
// likely just be in the noise anyway.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9034
void CMSCollector::restore_preserved_marks_if_any() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9035
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9036
         "world should be stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9037
  assert(Thread::current()->is_ConcurrentGC_thread() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9038
         Thread::current()->is_VM_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9039
         "should be single-threaded");
6762
f8d1b560700e 6423256: GC stacks should use a better data structure
jcoomes
parents: 6759
diff changeset
  9040
  assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(),
f8d1b560700e 6423256: GC stacks should use a better data structure
jcoomes
parents: 6759
diff changeset
  9041
         "bijection");
f8d1b560700e 6423256: GC stacks should use a better data structure
jcoomes
parents: 6759
diff changeset
  9042
f8d1b560700e 6423256: GC stacks should use a better data structure
jcoomes
parents: 6759
diff changeset
  9043
  while (!_preserved_oop_stack.is_empty()) {
f8d1b560700e 6423256: GC stacks should use a better data structure
jcoomes
parents: 6759
diff changeset
  9044
    oop p = _preserved_oop_stack.pop();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9045
    assert(p->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9046
    assert(_span.contains(p), "oop should be in _span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9047
    assert(p->mark() == markOopDesc::prototype(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9048
           "Set when taken from overflow list");
6762
f8d1b560700e 6423256: GC stacks should use a better data structure
jcoomes
parents: 6759
diff changeset
  9049
    markOop m = _preserved_mark_stack.pop();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9050
    p->set_mark(m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9051
  }
6762
f8d1b560700e 6423256: GC stacks should use a better data structure
jcoomes
parents: 6759
diff changeset
  9052
  assert(_preserved_mark_stack.is_empty() && _preserved_oop_stack.is_empty(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9053
         "stacks were cleared above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9054
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9055
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9056
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9057
bool CMSCollector::no_preserved_marks() const {
6762
f8d1b560700e 6423256: GC stacks should use a better data structure
jcoomes
parents: 6759
diff changeset
  9058
  return _preserved_mark_stack.is_empty() && _preserved_oop_stack.is_empty();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9059
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9060
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9061
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9062
CMSAdaptiveSizePolicy* ASConcurrentMarkSweepGeneration::cms_size_policy() const
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9063
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9064
  GenCollectedHeap* gch = (GenCollectedHeap*) GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9065
  CMSAdaptiveSizePolicy* size_policy =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9066
    (CMSAdaptiveSizePolicy*) gch->gen_policy()->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9067
  assert(size_policy->is_gc_cms_adaptive_size_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9068
    "Wrong type for size policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9069
  return size_policy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9070
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9071
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9072
void ASConcurrentMarkSweepGeneration::resize(size_t cur_promo_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9073
                                           size_t desired_promo_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9074
  if (cur_promo_size < desired_promo_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9075
    size_t expand_bytes = desired_promo_size - cur_promo_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9076
    if (PrintAdaptiveSizePolicy && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9077
      gclog_or_tty->print_cr(" ASConcurrentMarkSweepGeneration::resize "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9078
        "Expanding tenured generation by " SIZE_FORMAT " (bytes)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9079
        expand_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9080
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9081
    expand(expand_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9082
           MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9083
           CMSExpansionCause::_adaptive_size_policy);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9084
  } else if (desired_promo_size < cur_promo_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9085
    size_t shrink_bytes = cur_promo_size - desired_promo_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9086
    if (PrintAdaptiveSizePolicy && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9087
      gclog_or_tty->print_cr(" ASConcurrentMarkSweepGeneration::resize "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9088
        "Shrinking tenured generation by " SIZE_FORMAT " (bytes)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9089
        shrink_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9090
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9091
    shrink(shrink_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9092
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9093
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9094
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9095
CMSGCAdaptivePolicyCounters* ASConcurrentMarkSweepGeneration::gc_adaptive_policy_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9096
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9097
  CMSGCAdaptivePolicyCounters* counters =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9098
    (CMSGCAdaptivePolicyCounters*) gch->collector_policy()->counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9099
  assert(counters->kind() == GCPolicyCounters::CMSGCAdaptivePolicyCountersKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9100
    "Wrong kind of counters");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9101
  return counters;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9102
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9103
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9105
void ASConcurrentMarkSweepGeneration::update_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9106
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9107
    _space_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9108
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9109
    CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9110
    GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9111
    CMSGCStats* gc_stats_l = (CMSGCStats*) gc_stats();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9112
    assert(gc_stats_l->kind() == GCStats::CMSGCStatsKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9113
      "Wrong gc statistics type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9114
    counters->update_counters(gc_stats_l);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9115
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9116
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9117
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9118
void ASConcurrentMarkSweepGeneration::update_counters(size_t used) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9119
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9120
    _space_counters->update_used(used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9121
    _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9122
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9123
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9124
    CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9125
    GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9126
    CMSGCStats* gc_stats_l = (CMSGCStats*) gc_stats();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9127
    assert(gc_stats_l->kind() == GCStats::CMSGCStatsKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9128
      "Wrong gc statistics type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9129
    counters->update_counters(gc_stats_l);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9130
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9131
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9132
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9133
// The desired expansion delta is computed so that:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9134
// . desired free percentage or greater is used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9135
void ASConcurrentMarkSweepGeneration::compute_new_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9136
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9137
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9138
  GenCollectedHeap* gch = (GenCollectedHeap*) GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9139
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9140
  // If incremental collection failed, we just want to expand
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9141
  // to the limit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9142
  if (incremental_collection_failed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9143
    clear_incremental_collection_failed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9144
    grow_to_reserved();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9145
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9146
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9147
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9148
  assert(UseAdaptiveSizePolicy, "Should be using adaptive sizing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9149
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9150
  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9151
    "Wrong type of heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9152
  int prev_level = level() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9153
  assert(prev_level >= 0, "The cms generation is the lowest generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9154
  Generation* prev_gen = gch->get_gen(prev_level);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9155
  assert(prev_gen->kind() == Generation::ASParNew,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9156
    "Wrong type of young generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9157
  ParNewGeneration* younger_gen = (ParNewGeneration*) prev_gen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9158
  size_t cur_eden = younger_gen->eden()->capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9159
  CMSAdaptiveSizePolicy* size_policy = cms_size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9160
  size_t cur_promo = free();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9161
  size_policy->compute_tenured_generation_free_space(cur_promo,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9162
                                                       max_available(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9163
                                                       cur_eden);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9164
  resize(cur_promo, size_policy->promo_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9165
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9166
  // Record the new size of the space in the cms generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9167
  // that is available for promotions.  This is temporary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9168
  // It should be the desired promo size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9169
  size_policy->avg_cms_promo()->sample(free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9170
  size_policy->avg_old_live()->sample(used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9171
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9172
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9173
    CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9174
    counters->update_cms_capacity_counter(capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9175
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9176
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9177
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9178
void ASConcurrentMarkSweepGeneration::shrink_by(size_t desired_bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9179
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9180
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9181
  HeapWord* old_end = _cmsSpace->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9182
  HeapWord* unallocated_start = _cmsSpace->unallocated_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9183
  assert(old_end >= unallocated_start, "Miscalculation of unallocated_start");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9184
  FreeChunk* chunk_at_end = find_chunk_at_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9185
  if (chunk_at_end == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9186
    // No room to shrink
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9187
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9188
      gclog_or_tty->print_cr("No room to shrink: old_end  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9189
        PTR_FORMAT "  unallocated_start  " PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9190
        " chunk_at_end  " PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9191
        old_end, unallocated_start, chunk_at_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9192
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9193
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9194
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9195
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9196
    // Find the chunk at the end of the space and determine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9197
    // how much it can be shrunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9198
    size_t shrinkable_size_in_bytes = chunk_at_end->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9199
    size_t aligned_shrinkable_size_in_bytes =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9200
      align_size_down(shrinkable_size_in_bytes, os::vm_page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9201
    assert(unallocated_start <= chunk_at_end->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9202
      "Inconsistent chunk at end of space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9203
    size_t bytes = MIN2(desired_bytes, aligned_shrinkable_size_in_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9204
    size_t word_size_before = heap_word_size(_virtual_space.committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9205
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9206
    // Shrink the underlying space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9207
    _virtual_space.shrink_by(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9208
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9209
      gclog_or_tty->print_cr("ConcurrentMarkSweepGeneration::shrink_by:"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9210
        " desired_bytes " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9211
        " shrinkable_size_in_bytes " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9212
        " aligned_shrinkable_size_in_bytes " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9213
        "  bytes  " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9214
        desired_bytes, shrinkable_size_in_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9215
        aligned_shrinkable_size_in_bytes, bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9216
      gclog_or_tty->print_cr("          old_end  " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9217
        "  unallocated_start  " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9218
        old_end, unallocated_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9219
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9220
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9221
    // If the space did shrink (shrinking is not guaranteed),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9222
    // shrink the chunk at the end by the appropriate amount.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9223
    if (((HeapWord*)_virtual_space.high()) < old_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9224
      size_t new_word_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9225
        heap_word_size(_virtual_space.committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9226
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9227
      // Have to remove the chunk from the dictionary because it is changing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9228
      // size and might be someplace elsewhere in the dictionary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9229
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9230
      // Get the chunk at end, shrink it, and put it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9231
      // back.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9232
      _cmsSpace->removeChunkFromDictionary(chunk_at_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9233
      size_t word_size_change = word_size_before - new_word_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9234
      size_t chunk_at_end_old_size = chunk_at_end->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9235
      assert(chunk_at_end_old_size >= word_size_change,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9236
        "Shrink is too large");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9237
      chunk_at_end->setSize(chunk_at_end_old_size -
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9238
                          word_size_change);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9239
      _cmsSpace->freed((HeapWord*) chunk_at_end->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9240
        word_size_change);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9241
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9242
      _cmsSpace->returnChunkToDictionary(chunk_at_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9243
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9244
      MemRegion mr(_cmsSpace->bottom(), new_word_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9245
      _bts->resize(new_word_size);  // resize the block offset shared array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9246
      Universe::heap()->barrier_set()->resize_covered_region(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9247
      _cmsSpace->assert_locked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9248
      _cmsSpace->set_end((HeapWord*)_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9249
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9250
      NOT_PRODUCT(_cmsSpace->dictionary()->verify());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9251
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9252
      // update the space and generation capacity counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9253
      if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9254
        _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9255
        _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9256
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9257
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9258
      if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9259
        size_t new_mem_size = _virtual_space.committed_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9260
        size_t old_mem_size = new_mem_size + bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9261
        gclog_or_tty->print_cr("Shrinking %s from %ldK by %ldK to %ldK",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9262
                      name(), old_mem_size/K, bytes/K, new_mem_size/K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9263
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9264
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9265
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9266
    assert(_cmsSpace->unallocated_block() <= _cmsSpace->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9267
      "Inconsistency at end of space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9268
    assert(chunk_at_end->end() == _cmsSpace->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9269
      "Shrinking is inconsistent");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9270
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9271
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9272
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9273
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9274
// Transfer some number of overflown objects to usual marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9275
// stack. Return true if some objects were transferred.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9276
bool MarkRefsIntoAndScanClosure::take_from_overflow_list() {
2346
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  9277
  size_t num = MIN2((size_t)(_mark_stack->capacity() - _mark_stack->length())/4,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9278
                    (size_t)ParGCDesiredObjsFromOverflowList);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9279
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9280
  bool res = _collector->take_from_overflow_list(num, _mark_stack);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9281
  assert(_collector->overflow_list_is_empty() || res,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9282
         "If list is not empty, we should have taken something");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9283
  assert(!res || !_mark_stack->isEmpty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9284
         "If we took something, it should now be on our stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9285
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9286
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9287
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9288
size_t MarkDeadObjectsClosure::do_blk(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9289
  size_t res = _sp->block_size_no_stall(addr, _collector);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9290
  if (_sp->block_is_obj(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9291
    if (_live_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9292
      // It can't have been dead in a previous cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9293
      guarantee(!_dead_bit_map->isMarked(addr), "No resurrection!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9294
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9295
      _dead_bit_map->mark(addr);      // mark the dead object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9296
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9297
  }
8296
b1c2163e4e59 6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents: 8076
diff changeset
  9298
  // Could be 0, if the block size could not be computed without stalling.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9299
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9300
}
6245
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9301
9623
151c0b638488 7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents: 9342
diff changeset
  9302
TraceCMSMemoryManagerStats::TraceCMSMemoryManagerStats(CMSCollector::CollectorState phase, GCCause::Cause cause): TraceMemoryManagerStats() {
6245
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9303
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9304
  switch (phase) {
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9305
    case CMSCollector::InitialMarking:
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9306
      initialize(true  /* fullGC */ ,
9623
151c0b638488 7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents: 9342
diff changeset
  9307
                 cause /* cause of the GC */,
6245
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9308
                 true  /* recordGCBeginTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9309
                 true  /* recordPreGCUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9310
                 false /* recordPeakUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9311
                 false /* recordPostGCusage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9312
                 true  /* recordAccumulatedGCTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9313
                 false /* recordGCEndTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9314
                 false /* countCollection */  );
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9315
      break;
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9316
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9317
    case CMSCollector::FinalMarking:
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9318
      initialize(true  /* fullGC */ ,
9623
151c0b638488 7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents: 9342
diff changeset
  9319
                 cause /* cause of the GC */,
6245
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9320
                 false /* recordGCBeginTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9321
                 false /* recordPreGCUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9322
                 false /* recordPeakUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9323
                 false /* recordPostGCusage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9324
                 true  /* recordAccumulatedGCTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9325
                 false /* recordGCEndTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9326
                 false /* countCollection */  );
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9327
      break;
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9328
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9329
    case CMSCollector::Sweeping:
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9330
      initialize(true  /* fullGC */ ,
9623
151c0b638488 7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents: 9342
diff changeset
  9331
                 cause /* cause of the GC */,
6245
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9332
                 false /* recordGCBeginTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9333
                 false /* recordPreGCUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9334
                 true  /* recordPeakUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9335
                 true  /* recordPostGCusage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9336
                 false /* recordAccumulatedGCTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9337
                 true  /* recordGCEndTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9338
                 true  /* countCollection */  );
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9339
      break;
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9340
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9341
    default:
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9342
      ShouldNotReachHere();
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9343
  }
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9344
}
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9345