hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
author ysr
Mon, 16 Aug 2010 15:58:42 -0700
changeset 6258 68f252c6e825
parent 6246 2b94114ccaa4
child 6262 439992021ba8
permissions -rw-r--r--
6948538: CMS: BOT walkers can fall into object allocation and initialization cracks Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode. Reviewed-by: chrisphi, johnc, poonam
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5434
diff changeset
     2
 * Copyright (c) 2001, 2010, 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
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
# include "incls/_concurrentMarkSweepGeneration.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
// statics
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
CMSCollector* ConcurrentMarkSweepGeneration::_collector = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
bool          CMSCollector::_full_gc_requested          = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
// In support of CMS/VM thread synchronization
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
// We split use of the CGC_lock into 2 "levels".
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
// The low-level locking is of the usual CGC_lock monitor. We introduce
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
// a higher level "token" (hereafter "CMS token") built on top of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
// low level monitor (hereafter "CGC lock").
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
// The token-passing protocol gives priority to the VM thread. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
// CMS-lock doesn't provide any fairness guarantees, but clients
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
// should ensure that it is only held for very short, bounded
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
// durations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
// When either of the CMS thread or the VM thread is involved in
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
// collection operations during which it does not want the other
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
// thread to interfere, it obtains the CMS token.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
// If either thread tries to get the token while the other has
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
// it, that thread waits. However, if the VM thread and CMS thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
// both want the token, then the VM thread gets priority while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
// CMS thread waits. This ensures, for instance, that the "concurrent"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
// phases of the CMS thread's work do not block out the VM thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
// for long periods of time as the CMS thread continues to hog
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
// the token. (See bug 4616232).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
// The baton-passing functions are, however, controlled by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
// flags _foregroundGCShouldWait and _foregroundGCIsActive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
// and here the low-level CMS lock, not the high level token,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
// ensures mutual exclusion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
// Two important conditions that we have to satisfy:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
// 1. if a thread does a low-level wait on the CMS lock, then it
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
//    relinquishes the CMS token if it were holding that token
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
//    when it acquired the low-level CMS lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
// 2. any low-level notifications on the low-level lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
//    should only be sent when a thread has relinquished the token.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
// In the absence of either property, we'd have potential deadlock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
// We protect each of the CMS (concurrent and sequential) phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
// with the CMS _token_, not the CMS _lock_.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
// The only code protected by CMS lock is the token acquisition code
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
// itself, see ConcurrentMarkSweepThread::[de]synchronize(), and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
// baton-passing code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
// Unfortunately, i couldn't come up with a good abstraction to factor and
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
// hide the naked CGC_lock manipulation in the baton-passing code
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
// further below. That's something we should try to do. Also, the proof
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
// of correctness of this 2-level locking scheme is far from obvious,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
// and potentially quite slippery. We have an uneasy supsicion, for instance,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
// that there may be a theoretical possibility of delay/starvation in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
// low-level lock/wait/notify scheme used for the baton-passing because of
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
// potential intereference with the priority scheme embodied in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
// CMS-token-passing protocol. See related comments at a CGC_lock->wait()
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
// invocation further below and marked with "XXX 20011219YSR".
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
// Indeed, as we note elsewhere, this may become yet more slippery
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
// in the presence of multiple CMS and/or multiple VM threads. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
class CMSTokenSync: public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  bool _is_cms_thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  CMSTokenSync(bool is_cms_thread):
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
    _is_cms_thread(is_cms_thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    assert(is_cms_thread == Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
           "Incorrect argument to constructor");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
    ConcurrentMarkSweepThread::synchronize(_is_cms_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
  ~CMSTokenSync() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
    assert(_is_cms_thread ?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
             ConcurrentMarkSweepThread::cms_thread_has_cms_token() :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
             ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
          "Incorrect state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
    ConcurrentMarkSweepThread::desynchronize(_is_cms_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
// Convenience class that does a CMSTokenSync, and then acquires
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
// upto three locks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
class CMSTokenSyncWithLocks: public CMSTokenSync {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  // Note: locks are acquired in textual declaration order
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  // and released in the opposite order
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  MutexLockerEx _locker1, _locker2, _locker3;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  CMSTokenSyncWithLocks(bool is_cms_thread, Mutex* mutex1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
                        Mutex* mutex2 = NULL, Mutex* mutex3 = NULL):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
    CMSTokenSync(is_cms_thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
    _locker1(mutex1, Mutex::_no_safepoint_check_flag),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
    _locker2(mutex2, Mutex::_no_safepoint_check_flag),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
    _locker3(mutex3, Mutex::_no_safepoint_check_flag)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
// Wrapper class to temporarily disable icms during a foreground cms collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
class ICMSDisabler: public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  // The ctor disables icms and wakes up the thread so it notices the change;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  // the dtor re-enables icms.  Note that the CMSCollector methods will check
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  // CMSIncrementalMode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  ICMSDisabler()  { CMSCollector::disable_icms(); CMSCollector::start_icms(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  ~ICMSDisabler() { CMSCollector::enable_icms(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
//  Concurrent Mark-Sweep Generation /////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
NOT_PRODUCT(CompactibleFreeListSpace* debug_cms_space;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
// This struct contains per-thread things necessary to support parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
// young-gen collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
class CMSParGCThreadState: public CHeapObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  CFLS_LAB lab;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  PromotionInfo promo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  // Constructor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  CMSParGCThreadState(CompactibleFreeListSpace* cfls) : lab(cfls) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
    promo.setSpace(cfls);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
     ReservedSpace rs, size_t initial_byte_size, int level,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
     CardTableRS* ct, bool use_adaptive_freelists,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
     FreeBlockDictionary::DictionaryChoice dictionaryChoice) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  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
   162
  _dilatation_factor(((double)MinChunkSize)/((double)(CollectedHeap::min_fill_size()))),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  _debug_collection_type(Concurrent_collection_type)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  HeapWord* bottom = (HeapWord*) _virtual_space.low();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  HeapWord* end    = (HeapWord*) _virtual_space.high();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  _direct_allocated_words = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
    _numObjectsPromoted = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
    _numWordsPromoted = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    _numObjectsAllocated = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    _numWordsAllocated = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  _cmsSpace = new CompactibleFreeListSpace(_bts, MemRegion(bottom, end),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
                                           use_adaptive_freelists,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
                                           dictionaryChoice);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  NOT_PRODUCT(debug_cms_space = _cmsSpace;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  if (_cmsSpace == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
    vm_exit_during_initialization(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
      "CompactibleFreeListSpace allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  _cmsSpace->_gen = this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  _gc_stats = new CMSGCStats();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  // Verify the assumption that FreeChunk::_prev and OopDesc::_klass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  // offsets match. The ability to tell free chunks from objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
  // depends on this property.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  debug_only(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
    FreeChunk* junk = NULL;
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
   193
    assert(UseCompressedOops ||
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
   194
           junk->prev_addr() == (void*)(oop(junk)->klass_addr()),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
           "Offset of FreeChunk::_prev within FreeChunk must match"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
           "  that of OopDesc::_klass within OopDesc");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  if (ParallelGCThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    typedef CMSParGCThreadState* CMSParGCThreadStatePtr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
    _par_gc_thread_states =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
      NEW_C_HEAP_ARRAY(CMSParGCThreadStatePtr, ParallelGCThreads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
    if (_par_gc_thread_states == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
      vm_exit_during_initialization("Could not allocate par gc structs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
    for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
      _par_gc_thread_states[i] = new CMSParGCThreadState(cmsSpace());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
      if (_par_gc_thread_states[i] == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
        vm_exit_during_initialization("Could not allocate par gc structs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
    _par_gc_thread_states = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  _incremental_collection_failed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  // The "dilatation_factor" is the expansion that can occur on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  // account of the fact that the minimum object size in the CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
  // generation may be larger than that in, say, a contiguous young
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  //  generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  // Ideally, in the calculation below, we'd compute the dilatation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  // factor as: MinChunkSize/(promoting_gen's min object size)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  // Since we do not have such a general query interface for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
  // promoting generation, we'll instead just use the mimimum
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  // object size (which today is a header's worth of space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  // 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
   225
  assert(MinChunkSize >= CollectedHeap::min_fill_size(), "just checking");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  assert(_dilatation_factor >= 1.0, "from previous assert");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   229
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   230
// The field "_initiating_occupancy" represents the occupancy percentage
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   231
// 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
   232
// via CMSInitiating[Perm]OccupancyFraction (argument "io" below), it
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   233
// is calculated by:
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   234
//
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   235
//   Let "f" be MinHeapFreeRatio in
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   236
//
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   237
//    _intiating_occupancy = 100-f +
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   238
//                           f * (CMSTrigger[Perm]Ratio/100)
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   239
//   where CMSTrigger[Perm]Ratio is the argument "tr" below.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   240
//
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   241
// 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
   242
// 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
   243
// space be allocated before initiating a new collection cycle.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   244
//
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   245
void ConcurrentMarkSweepGeneration::init_initiating_occupancy(intx io, intx tr) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   246
  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
   247
  if (io >= 0) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   248
    _initiating_occupancy = (double)io / 100.0;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   249
  } else {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   250
    _initiating_occupancy = ((100 - MinHeapFreeRatio) +
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   251
                             (double)(tr * MinHeapFreeRatio) / 100.0)
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   252
                            / 100.0;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   253
  }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   254
}
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   255
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
void ConcurrentMarkSweepGeneration::ref_processor_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  assert(collector() != NULL, "no collector");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  collector()->ref_processor_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
void CMSCollector::ref_processor_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  if (_ref_processor == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
    // Allocate and initialize a reference processor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
    _ref_processor = ReferenceProcessor::create_ref_processor(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
        _span,                               // span
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
        _cmsGen->refs_discovery_is_atomic(), // atomic_discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
        _cmsGen->refs_discovery_is_mt(),     // mt_discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
        &_is_alive_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
        ParallelGCThreads,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
        ParallelRefProcEnabled);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
    // Initialize the _ref_processor field of CMSGen
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
    _cmsGen->set_ref_processor(_ref_processor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
    // Allocate a dummy ref processor for perm gen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
    ReferenceProcessor* rp2 = new ReferenceProcessor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
    if (rp2 == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
      vm_exit_during_initialization("Could not allocate ReferenceProcessor object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
    _permGen->set_ref_processor(rp2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
CMSAdaptiveSizePolicy* CMSCollector::size_policy() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
    "Wrong type of heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  CMSAdaptiveSizePolicy* sp = (CMSAdaptiveSizePolicy*)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
    gch->gen_policy()->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  assert(sp->is_gc_cms_adaptive_size_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
    "Wrong type of size policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  return sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
CMSGCAdaptivePolicyCounters* CMSCollector::gc_adaptive_policy_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  CMSGCAdaptivePolicyCounters* results =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
    (CMSGCAdaptivePolicyCounters*) collector_policy()->counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  assert(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
    results->kind() == GCPolicyCounters::CMSGCAdaptivePolicyCountersKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    "Wrong gc policy counter kind");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
  return results;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
void ConcurrentMarkSweepGeneration::initialize_performance_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  const char* gen_name = "old";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  // Generation Counters - generation 1, 1 subspace
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
  _gen_counters = new GenerationCounters(gen_name, 1, 1, &_virtual_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  _space_counters = new GSpaceCounters(gen_name, 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
                                       _virtual_space.reserved_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
                                       this, _gen_counters);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
CMSStats::CMSStats(ConcurrentMarkSweepGeneration* cms_gen, unsigned int alpha):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  _cms_gen(cms_gen)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
  assert(alpha <= 100, "bad value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  _saved_alpha = alpha;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
  // Initialize the alphas to the bootstrap value of 100.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
  _gc0_alpha = _cms_alpha = 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
  _cms_begin_time.update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  _cms_end_time.update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  _gc0_duration = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  _gc0_period = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  _gc0_promoted = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  _cms_duration = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  _cms_period = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  _cms_allocated = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  _cms_used_at_gc0_begin = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  _cms_used_at_gc0_end = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
  _allow_duty_cycle_reduction = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  _valid_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  _icms_duty_cycle = CMSIncrementalDutyCycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   343
double CMSStats::cms_free_adjustment_factor(size_t free) const {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   344
  // TBD: CR 6909490
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   345
  return 1.0;
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   346
}
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   347
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   348
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
   349
}
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   350
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
// If promotion failure handling is on use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
// the padded average size of the promotion for each
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
// young generation collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
double CMSStats::time_until_cms_gen_full() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  size_t cms_free = _cms_gen->cmsSpace()->free();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
  size_t expected_promotion = gch->get_gen(0)->capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  if (HandlePromotionFailure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
    expected_promotion = MIN2(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
        (size_t) _cms_gen->gc_stats()->avg_promoted()->padded_average(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
        expected_promotion);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  if (cms_free > expected_promotion) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
    // Start a cms collection if there isn't enough space to promote
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
    // for the next minor collection.  Use the padded average as
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
    // a safety factor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
    cms_free -= expected_promotion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
    // Adjust by the safety factor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
    double cms_free_dbl = (double)cms_free;
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   371
    double cms_adjustment = (100.0 - CMSIncrementalSafetyFactor)/100.0;
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   372
    // Apply a further correction factor which tries to adjust
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   373
    // for recent occurance of concurrent mode failures.
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   374
    cms_adjustment = cms_adjustment * cms_free_adjustment_factor(cms_free);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   375
    cms_free_dbl = cms_free_dbl * cms_adjustment;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
      gclog_or_tty->print_cr("CMSStats::time_until_cms_gen_full: cms_free "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
        SIZE_FORMAT " expected_promotion " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
        cms_free, expected_promotion);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
      gclog_or_tty->print_cr("  cms_free_dbl %f cms_consumption_rate %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
        cms_free_dbl, cms_consumption_rate() + 1.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
    // Add 1 in case the consumption rate goes to zero.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
    return cms_free_dbl / (cms_consumption_rate() + 1.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  return 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
// Compare the duration of the cms collection to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
// time remaining before the cms generation is empty.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
// Note that the time from the start of the cms collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
// to the start of the cms sweep (less than the total
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
// duration of the cms collection) can be used.  This
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
// has been tried and some applications experienced
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
// promotion failures early in execution.  This was
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
// possibly because the averages were not accurate
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
// enough at the beginning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
double CMSStats::time_until_cms_start() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  // We add "gc0_period" to the "work" calculation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  // below because this query is done (mostly) at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  // end of a scavenge, so we need to conservatively
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
  // account for that much possible delay
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  // in the query so as to avoid concurrent mode failures
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
  // due to starting the collection just a wee bit too
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
  // late.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  double work = cms_duration() + gc0_period();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  double deadline = time_until_cms_gen_full();
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   409
  // If a concurrent mode failure occurred recently, we want to be
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   410
  // more conservative and halve our expected time_until_cms_gen_full()
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  if (work > deadline) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
      gclog_or_tty->print(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
        " CMSCollector: collect because of anticipated promotion "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
        "before full %3.7f + %3.7f > %3.7f ", cms_duration(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
        gc0_period(), time_until_cms_gen_full());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
    return 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  return work - deadline;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
// Return a duty cycle based on old_duty_cycle and new_duty_cycle, limiting the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
// amount of change to prevent wild oscillation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
unsigned int CMSStats::icms_damped_duty_cycle(unsigned int old_duty_cycle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
                                              unsigned int new_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  assert(old_duty_cycle <= 100, "bad input value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
  assert(new_duty_cycle <= 100, "bad input value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
  // Note:  use subtraction with caution since it may underflow (values are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  // unsigned).  Addition is safe since we're in the range 0-100.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  unsigned int damped_duty_cycle = new_duty_cycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  if (new_duty_cycle < old_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
    const unsigned int largest_delta = MAX2(old_duty_cycle / 4, 5U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
    if (new_duty_cycle + largest_delta < old_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
      damped_duty_cycle = old_duty_cycle - largest_delta;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  } else if (new_duty_cycle > old_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
    const unsigned int largest_delta = MAX2(old_duty_cycle / 4, 15U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
    if (new_duty_cycle > old_duty_cycle + largest_delta) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
      damped_duty_cycle = MIN2(old_duty_cycle + largest_delta, 100U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  assert(damped_duty_cycle <= 100, "invalid duty cycle computed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
  if (CMSTraceIncrementalPacing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
    gclog_or_tty->print(" [icms_damped_duty_cycle(%d,%d) = %d] ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
                           old_duty_cycle, new_duty_cycle, damped_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  return damped_duty_cycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
unsigned int CMSStats::icms_update_duty_cycle_impl() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
  assert(CMSIncrementalPacing && valid(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
         "should be handled in icms_update_duty_cycle()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  double cms_time_so_far = cms_timer().seconds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  double scaled_duration = cms_duration_per_mb() * _cms_used_at_gc0_end / M;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  double scaled_duration_remaining = fabsd(scaled_duration - cms_time_so_far);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  // Avoid division by 0.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
  double time_until_full = MAX2(time_until_cms_gen_full(), 0.01);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  double duty_cycle_dbl = 100.0 * scaled_duration_remaining / time_until_full;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  unsigned int new_duty_cycle = MIN2((unsigned int)duty_cycle_dbl, 100U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  if (new_duty_cycle > _icms_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
    // Avoid very small duty cycles (1 or 2); 0 is allowed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
    if (new_duty_cycle > 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
      _icms_duty_cycle = icms_damped_duty_cycle(_icms_duty_cycle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
                                                new_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  } else if (_allow_duty_cycle_reduction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
    // The duty cycle is reduced only once per cms cycle (see record_cms_end()).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
    new_duty_cycle = icms_damped_duty_cycle(_icms_duty_cycle, new_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
    // Respect the minimum duty cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
    unsigned int min_duty_cycle = (unsigned int)CMSIncrementalDutyCycleMin;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
    _icms_duty_cycle = MAX2(new_duty_cycle, min_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
  if (PrintGCDetails || CMSTraceIncrementalPacing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
    gclog_or_tty->print(" icms_dc=%d ", _icms_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
  _allow_duty_cycle_reduction = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
  return _icms_duty_cycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
void CMSStats::print_on(outputStream *st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  st->print(" gc0_alpha=%d,cms_alpha=%d", _gc0_alpha, _cms_alpha);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  st->print(",gc0_dur=%g,gc0_per=%g,gc0_promo=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
               gc0_duration(), gc0_period(), gc0_promoted());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
  st->print(",cms_dur=%g,cms_dur_per_mb=%g,cms_per=%g,cms_alloc=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
            cms_duration(), cms_duration_per_mb(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
            cms_period(), cms_allocated());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
  st->print(",cms_since_beg=%g,cms_since_end=%g",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
            cms_time_since_begin(), cms_time_since_end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
  st->print(",cms_used_beg=" SIZE_FORMAT ",cms_used_end=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
            _cms_used_at_gc0_begin, _cms_used_at_gc0_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
  if (CMSIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
    st->print(",dc=%d", icms_duty_cycle());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  if (valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
    st->print(",promo_rate=%g,cms_alloc_rate=%g",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
              promotion_rate(), cms_allocation_rate());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
    st->print(",cms_consumption_rate=%g,time_until_full=%g",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
              cms_consumption_rate(), time_until_cms_gen_full());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  st->print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
#endif // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
CMSCollector::CollectorState CMSCollector::_collectorState =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
                             CMSCollector::Idling;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
bool CMSCollector::_foregroundGCIsActive = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
bool CMSCollector::_foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
                           ConcurrentMarkSweepGeneration* permGen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
                           CardTableRS*                   ct,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
                           ConcurrentMarkSweepPolicy*     cp):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  _cmsGen(cmsGen),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  _permGen(permGen),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  _ct(ct),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  _ref_processor(NULL),    // will be set later
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  _conc_workers(NULL),     // may be set later
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  _abort_preclean(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  _start_sampling(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  _between_prologue_and_epilogue(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  _markBitMap(0, Mutex::leaf + 1, "CMS_markBitMap_lock"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  _perm_gen_verify_bit_map(0, -1 /* no mutex */, "No_lock"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  _modUnionTable((CardTableModRefBS::card_shift - LogHeapWordSize),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
                 -1 /* lock-free */, "No_lock" /* dummy */),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
  _modUnionClosure(&_modUnionTable),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  _modUnionClosurePar(&_modUnionTable),
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   537
  // 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
   538
  _span(cmsGen->reserved()._union(permGen->reserved())),
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   539
  // Construct the is_alive_closure with _span & markBitMap
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   540
  _is_alive_closure(_span, &_markBitMap),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  _restart_addr(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
  _overflow_list(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
  _preserved_oop_stack(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
  _preserved_mark_stack(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
  _stats(cmsGen),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
  _eden_chunk_array(NULL),     // may be set in ctor body
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  _eden_chunk_capacity(0),     // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
  _eden_chunk_index(0),        // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
  _survivor_plab_array(NULL),  // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
  _survivor_chunk_array(NULL), // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
  _survivor_chunk_capacity(0), // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  _survivor_chunk_index(0),    // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
  _ser_pmc_preclean_ovflw(0),
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
   554
  _ser_kac_preclean_ovflw(0),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  _ser_pmc_remark_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
  _par_pmc_remark_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
  _ser_kac_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
  _par_kac_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  _num_par_pushes(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
  _collection_count_start(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
  _verifying(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
  _icms_start_limit(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  _icms_stop_limit(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  _verification_mark_bm(0, Mutex::leaf + 1, "CMS_verification_mark_bm_lock"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  _completed_initialization(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  _collector_policy(cp),
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   569
  _should_unload_classes(false),
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   570
  _concurrent_cycles_since_last_unload(0),
2885
7dd49b9daa4a 6848641: CMSCollector::_roots_scanning_options should be initialized
ysr
parents: 2346
diff changeset
   571
  _roots_scanning_options(0),
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   572
  _inter_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   573
  _intra_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
  if (ExplicitGCInvokesConcurrentAndUnloadsClasses) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
    ExplicitGCInvokesConcurrent = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  // Now expand the span and allocate the collection support structures
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  // (MUT, marking bit map etc.) to cover both generations subject to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  // collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  // First check that _permGen is adjacent to _cmsGen and above it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
  assert(   _cmsGen->reserved().word_size()  > 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
         && _permGen->reserved().word_size() > 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
         "generations should not be of zero size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
  assert(_cmsGen->reserved().intersection(_permGen->reserved()).is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
         "_cmsGen and _permGen should not overlap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
  assert(_cmsGen->reserved().end() == _permGen->reserved().start(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
         "_cmsGen->end() different from _permGen->start()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  // For use by dirty card to oop closures.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
  _cmsGen->cmsSpace()->set_collector(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  _permGen->cmsSpace()->set_collector(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  // Allocate MUT and marking bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
    MutexLockerEx x(_markBitMap.lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
    if (!_markBitMap.allocate(_span)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
      warning("Failed to allocate CMS Bit Map");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
    assert(_markBitMap.covers(_span), "_markBitMap inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
    _modUnionTable.allocate(_span);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
    assert(_modUnionTable.covers(_span), "_modUnionTable inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   609
  if (!_markStack.allocate(MarkStackSize)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
    warning("Failed to allocate CMS Marking Stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
  if (!_revisitStack.allocate(CMSRevisitStackSize)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
    warning("Failed to allocate CMS Revisit Stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  // Support for multi-threaded concurrent phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
  if (ParallelGCThreads > 0 && CMSConcurrentMTEnabled) {
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   620
    if (FLAG_IS_DEFAULT(ConcGCThreads)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
      // just for now
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   622
      FLAG_SET_DEFAULT(ConcGCThreads, (ParallelGCThreads + 3)/4);
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   623
    }
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   624
    if (ConcGCThreads > 1) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
      _conc_workers = new YieldingFlexibleWorkGang("Parallel CMS Threads",
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   626
                                 ConcGCThreads, true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
      if (_conc_workers == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
        warning("GC/CMS: _conc_workers allocation failure: "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
              "forcing -CMSConcurrentMTEnabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
        CMSConcurrentMTEnabled = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
      CMSConcurrentMTEnabled = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
  if (!CMSConcurrentMTEnabled) {
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   637
    ConcGCThreads = 0;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
    // Turn off CMSCleanOnEnter optimization temporarily for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
    // the MT case where it's not fixed yet; see 6178663.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
    CMSCleanOnEnter = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
  }
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   643
  assert((_conc_workers != NULL) == (ConcGCThreads > 1),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
         "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
  // Parallel task queues; these are shared for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
  // concurrent and stop-world phases of CMS, but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
  // are not shared with parallel scavenge (ParNew).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
    uint i;
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
   651
    uint num_queues = (uint) MAX2(ParallelGCThreads, ConcGCThreads);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
    if ((CMSParallelRemarkEnabled || CMSConcurrentMTEnabled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
         || ParallelRefProcEnabled)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
        && num_queues > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
      _task_queues = new OopTaskQueueSet(num_queues);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
      if (_task_queues == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
        warning("task_queues allocation failure.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
      _hash_seed = NEW_C_HEAP_ARRAY(int, num_queues);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
      if (_hash_seed == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
        warning("_hash_seed array allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
6067
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5702
diff changeset
   667
      typedef Padded<OopTaskQueue> PaddedOopTaskQueue;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
      for (i = 0; i < num_queues; i++) {
6067
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5702
diff changeset
   669
        PaddedOopTaskQueue *q = new PaddedOopTaskQueue();
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5702
diff changeset
   670
        if (q == NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
          warning("work_queue allocation failure.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
        }
6067
8bfddf73fc04 6962947: shared TaskQueue statistics
jcoomes
parents: 5702
diff changeset
   674
        _task_queues->register_queue(i, q);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
      for (i = 0; i < num_queues; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
        _task_queues->queue(i)->initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
        _hash_seed[i] = 17;  // copied from ParNew
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   683
  _cmsGen ->init_initiating_occupancy(CMSInitiatingOccupancyFraction, CMSTriggerRatio);
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   684
  _permGen->init_initiating_occupancy(CMSInitiatingPermOccupancyFraction, CMSTriggerPermRatio);
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   685
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
  // Clip CMSBootstrapOccupancy between 0 and 100.
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   687
  _bootstrap_occupancy = ((double)MIN2((uintx)100, MAX2((uintx)0, CMSBootstrapOccupancy)))
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
                         /(double)100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
  _full_gcs_since_conc_gc = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
  // Now tell CMS generations the identity of their collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
  ConcurrentMarkSweepGeneration::set_collector(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
  // Create & start a CMS thread for this CMS collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
  _cmsThread = ConcurrentMarkSweepThread::start(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
  assert(cmsThread() != NULL, "CMS Thread should have been created");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
  assert(cmsThread()->collector() == this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
         "CMS Thread should refer to this gen");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
  assert(CGC_lock != NULL, "Where's the CGC_lock?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
  // Support for parallelizing young gen rescan
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
  _young_gen = gch->prev_gen(_cmsGen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
  if (gch->supports_inline_contig_alloc()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
    _top_addr = gch->top_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
    _end_addr = gch->end_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
    assert(_young_gen != NULL, "no _young_gen");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
    _eden_chunk_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
    _eden_chunk_capacity = (_young_gen->max_capacity()+CMSSamplingGrain)/CMSSamplingGrain;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
    _eden_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, _eden_chunk_capacity);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
    if (_eden_chunk_array == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
      _eden_chunk_capacity = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
      warning("GC/CMS: _eden_chunk_array allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
  assert(_eden_chunk_array != NULL || _eden_chunk_capacity == 0, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
  // Support for parallelizing survivor space rescan
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
  if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
5040
529add9be0d5 6910182: CMS: assert(_cursor[j] == _survivor_plab_array[j].end(),"Ctl pt invariant")
jmasa
parents: 5035
diff changeset
   721
    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
   722
      ((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
   723
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
    _survivor_plab_array  = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
    _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
    _cursor               = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
    if (_survivor_plab_array == NULL || _survivor_chunk_array == NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
        || _cursor == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
      warning("Failed to allocate survivor plab/chunk array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
      if (_survivor_plab_array  != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
        FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
        _survivor_plab_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
      if (_survivor_chunk_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
        FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
        _survivor_chunk_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
      if (_cursor != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
        FREE_C_HEAP_ARRAY(size_t, _cursor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
        _cursor = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
      _survivor_chunk_capacity = 2*max_plab_samples;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
      for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
        HeapWord** vec = NEW_C_HEAP_ARRAY(HeapWord*, max_plab_samples);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
        if (vec == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
          warning("Failed to allocate survivor plab array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
          for (int j = i; j > 0; j--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
            FREE_C_HEAP_ARRAY(HeapWord*, _survivor_plab_array[j-1].array());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
          FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
          FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
          _survivor_plab_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
          _survivor_chunk_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
          _survivor_chunk_capacity = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
          ChunkArray* cur =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
            ::new (&_survivor_plab_array[i]) ChunkArray(vec,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
                                                        max_plab_samples);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
          assert(cur->end() == 0, "Should be 0");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
          assert(cur->array() == vec, "Should be vec");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
          assert(cur->capacity() == max_plab_samples, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
  assert(   (   _survivor_plab_array  != NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
             && _survivor_chunk_array != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
         || (   _survivor_chunk_capacity == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
             && _survivor_chunk_index == 0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
         "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
  // Choose what strong roots should be scanned depending on verification options
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
  // and perm gen collection mode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
  if (!CMSClassUnloadingEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
    // If class unloading is disabled we want to include all classes into the root set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
    add_root_scanning_option(SharedHeap::SO_AllClasses);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
    add_root_scanning_option(SharedHeap::SO_SystemClasses);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
  NOT_PRODUCT(_overflow_counter = CMSMarkStackOverflowInterval;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
  _gc_counters = new CollectorCounters("CMS", 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
  _completed_initialization = true;
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   786
  _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
   787
#ifdef SPARC
5c4054a50dbb 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 5343
diff changeset
   788
  // 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
   789
  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
   790
    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
   791
    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
   792
            " 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
   793
  }
5c4054a50dbb 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT
ysr
parents: 5343
diff changeset
   794
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
const char* ConcurrentMarkSweepGeneration::name() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
  return "concurrent mark-sweep generation";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
void ConcurrentMarkSweepGeneration::update_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
    _space_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
// this is an optimized version of update_counters(). it takes the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
// used value as a parameter rather than computing it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
void ConcurrentMarkSweepGeneration::update_counters(size_t used) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
    _space_counters->update_used(used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
    _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
void ConcurrentMarkSweepGeneration::print() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
  Generation::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
  cmsSpace()->print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
void ConcurrentMarkSweepGeneration::print_statistics() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
  cmsSpace()->printFLCensus(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
void ConcurrentMarkSweepGeneration::printOccupancy(const char *s) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
  if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
    if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
      gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
        level(), short_name(), s, used(), capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
      gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
        level(), short_name(), s, used() / K, capacity() / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
  if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
    gclog_or_tty->print(" "SIZE_FORMAT"("SIZE_FORMAT")",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
              gch->used(), gch->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
    gclog_or_tty->print(" "SIZE_FORMAT"K("SIZE_FORMAT"K)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
              gch->used() / K, gch->capacity() / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
size_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
ConcurrentMarkSweepGeneration::contiguous_available() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
  // dld proposes an improvement in precision here. If the committed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
  // part of the space ends in a free block we should add that to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
  // uncommitted size in the calculation below. Will make this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
  // change later, staying with the approximation below for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
  // time being. -- ysr.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
  return MAX2(_virtual_space.uncommitted_size(), unsafe_max_alloc_nogc());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
size_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
ConcurrentMarkSweepGeneration::unsafe_max_alloc_nogc() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
  return _cmsSpace->max_alloc_in_words() * HeapWordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
size_t ConcurrentMarkSweepGeneration::max_available() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
  return free() + _virtual_space.uncommitted_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
bool ConcurrentMarkSweepGeneration::promotion_attempt_is_safe(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
    size_t max_promotion_in_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
    bool younger_handles_promotion_failure) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
  // This is the most conservative test.  Full promotion is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
  // guaranteed if this is used. The multiplicative factor is to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
  // account for the worst case "dilatation".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
  double adjusted_max_promo_bytes = _dilatation_factor * max_promotion_in_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
  if (adjusted_max_promo_bytes > (double)max_uintx) { // larger than size_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
    adjusted_max_promo_bytes = (double)max_uintx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
  bool result = (max_contiguous_available() >= (size_t)adjusted_max_promo_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
  if (younger_handles_promotion_failure && !result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
    // Full promotion is not guaranteed because fragmentation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
    // of the cms generation can prevent the full promotion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
    result = (max_available() >= (size_t)adjusted_max_promo_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
    if (!result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
      // With promotion failure handling the test for the ability
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
      // to support the promotion does not have to be guaranteed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
      // Use an average of the amount promoted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
      result = max_available() >= (size_t)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
        gc_stats()->avg_promoted()->padded_average();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
      if (PrintGC && Verbose && result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
        gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
          "\nConcurrentMarkSweepGeneration::promotion_attempt_is_safe"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
          " max_available: " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
          " avg_promoted: " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
          max_available(), (size_t)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
          gc_stats()->avg_promoted()->padded_average());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
      if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
        gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
          "\nConcurrentMarkSweepGeneration::promotion_attempt_is_safe"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
          " max_available: " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
          " adj_max_promo_bytes: " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
          max_available(), (size_t)adjusted_max_promo_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
    if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
      gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
        "\nConcurrentMarkSweepGeneration::promotion_attempt_is_safe"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
        " contiguous_available: " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
        " adj_max_promo_bytes: " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
        max_contiguous_available(), (size_t)adjusted_max_promo_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   921
// At a promotion failure dump information on block layout in heap
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   922
// (cms old generation).
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   923
void ConcurrentMarkSweepGeneration::promotion_failure_occurred() {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   924
  if (CMSDumpAtPromotionFailure) {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   925
    cmsSpace()->dump_at_safepoint_with_locks(collector(), gclog_or_tty);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   926
  }
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   927
}
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   928
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
CompactibleSpace*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
ConcurrentMarkSweepGeneration::first_compaction_space() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
  return _cmsSpace;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
void ConcurrentMarkSweepGeneration::reset_after_compaction() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
  // Clear the promotion information.  These pointers can be adjusted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
  // along with all the other pointers into the heap but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
  // compaction is expected to be a rare event with
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
  // a heap using cms so don't do it without seeing the need.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
  if (ParallelGCThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
    for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
      _par_gc_thread_states[i]->promo.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
void ConcurrentMarkSweepGeneration::space_iterate(SpaceClosure* blk, bool usedOnly) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
  blk->do_space(_cmsSpace);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
void ConcurrentMarkSweepGeneration::compute_new_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
  // If incremental collection failed, we just want to expand
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
  // to the limit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
  if (incremental_collection_failed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
    clear_incremental_collection_failed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
    grow_to_reserved();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
  size_t expand_bytes = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
  double free_percentage = ((double) free()) / capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
  double desired_free_percentage = (double) MinHeapFreeRatio / 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
  double maximum_free_percentage = (double) MaxHeapFreeRatio / 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
  // compute expansion delta needed for reaching desired free percentage
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
  if (free_percentage < desired_free_percentage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
    size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
    assert(desired_capacity >= capacity(), "invalid expansion size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
    expand_bytes = MAX2(desired_capacity - capacity(), MinHeapDeltaBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
  if (expand_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
      size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
      gclog_or_tty->print_cr("\nFrom compute_new_size: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
      gclog_or_tty->print_cr("  Free fraction %f", free_percentage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
      gclog_or_tty->print_cr("  Desired free fraction %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
        desired_free_percentage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
      gclog_or_tty->print_cr("  Maximum free fraction %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
        maximum_free_percentage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
      gclog_or_tty->print_cr("  Capactiy "SIZE_FORMAT, capacity()/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
      gclog_or_tty->print_cr("  Desired capacity "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
        desired_capacity/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
      int prev_level = level() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
      if (prev_level >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
        size_t prev_size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
        GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
        Generation* prev_gen = gch->_gens[prev_level];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
        prev_size = prev_gen->capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
          gclog_or_tty->print_cr("  Younger gen size "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
                                 prev_size/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
      gclog_or_tty->print_cr("  unsafe_max_alloc_nogc "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
        unsafe_max_alloc_nogc()/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
      gclog_or_tty->print_cr("  contiguous available "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
        contiguous_available()/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
      gclog_or_tty->print_cr("  Expand by "SIZE_FORMAT" (bytes)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
        expand_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
    // safe if expansion fails
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
    expand(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
      gclog_or_tty->print_cr("  Expanded free fraction %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
        ((double) free()) / capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
Mutex* ConcurrentMarkSweepGeneration::freelistLock() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
  return cmsSpace()->freelistLock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
HeapWord* ConcurrentMarkSweepGeneration::allocate(size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
                                                  bool   tlab) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
  CMSSynchronousYieldRequest yr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
  MutexLockerEx x(freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
                  Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
  return have_lock_and_allocate(size, tlab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
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
  1022
                                                  bool   tlab /* ignored */) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
  size_t adjustedSize = CompactibleFreeListSpace::adjustObjectSize(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
  HeapWord* res = cmsSpace()->allocate(adjustedSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
  // Allocate the object live (grey) if the background collector has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
  // started marking. This is necessary because the marker may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
  // have passed this address and consequently this object will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
  // not otherwise be greyed and would be incorrectly swept up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
  // Note that if this object contains references, the writing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
  // of those references will dirty the card containing this object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
  // allowing the object to be blackened (and its references scanned)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
  // either during a preclean phase or at the final checkpoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
  if (res != NULL) {
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1035
    // 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
  1036
    // 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
  1037
    // 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
  1038
    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
  1039
    assert(!((FreeChunk*)res)->isFree(), "Error, block will look free but show wrong size");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
    collector()->direct_allocated(res, adjustedSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
    _direct_allocated_words += adjustedSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
    // allocation counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
      _numObjectsAllocated++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
      _numWordsAllocated += (int)adjustedSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
// In the case of direct allocation by mutators in a generation that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
// is being concurrently collected, the object must be allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
// live (grey) if the background collector has started marking.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
// This is necessary because the marker may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
// have passed this address and consequently this object will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
// not otherwise be greyed and would be incorrectly swept up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
// Note that if this object contains references, the writing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
// of those references will dirty the card containing this object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
// allowing the object to be blackened (and its references scanned)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
// either during a preclean phase or at the final checkpoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
void CMSCollector::direct_allocated(HeapWord* start, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
  assert(_markBitMap.covers(start, size), "Out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
  if (_collectorState >= Marking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
    MutexLockerEx y(_markBitMap.lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
                    Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
    // [see comments preceding SweepClosure::do_blk() below for details]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
    // 1. need to mark the object as live so it isn't collected
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
    // 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
  1069
    // 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
  1070
    //    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
  1071
    //    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
  1072
    //    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
  1073
    //    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
  1074
    //    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
  1075
    //    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
  1076
    //    as soon as they are initialized.)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
    _markBitMap.mark(start);          // object is live
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
    _markBitMap.mark(start + 1);      // object is potentially uninitialized?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
    _markBitMap.mark(start + size - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
                                      // mark end of object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
  // check that oop looks uninitialized
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1083
  assert(oop(start)->klass_or_null() == NULL, "_klass should be NULL");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
void CMSCollector::promoted(bool par, HeapWord* start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
                            bool is_obj_array, size_t obj_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
  assert(_markBitMap.covers(start), "Out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
  // See comment in direct_allocated() about when objects should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
  // be allocated live.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
  if (_collectorState >= Marking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
    // we already hold the marking bit map lock, taken in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
    // the prologue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
    if (par) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
      _markBitMap.par_mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
      _markBitMap.mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
    // We don't need to mark the object as uninitialized (as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
    // in direct_allocated above) because this is being done with the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
    // 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
  1102
    // 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
  1103
    // 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
  1104
    // 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
  1105
    // 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
  1106
    // 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
  1107
    // 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
  1108
    // becoming a bona-fide object when the copy/promotion is complete.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
    assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
           "expect promotion only at safepoints");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
    if (_collectorState < Sweeping) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
      // Mark the appropriate cards in the modUnionTable, so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
      // this object gets scanned before the sweep. If this is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
      // not done, CMS generation references in the object might
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
      // not get marked.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
      // For the case of arrays, which are otherwise precisely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
      // marked, we need to dirty the entire array, not just its head.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
      if (is_obj_array) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
        // The [par_]mark_range() method expects mr.end() below to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
        // be aligned to the granularity of a bit's representation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
        // in the heap. In the case of the MUT below, that's a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
        // card size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
        MemRegion mr(start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
                     (HeapWord*)round_to((intptr_t)(start + obj_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
                        CardTableModRefBS::card_size /* bytes */));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
        if (par) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
          _modUnionTable.par_mark_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
          _modUnionTable.mark_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
      } else {  // not an obj array; we can just mark the head
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
        if (par) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
          _modUnionTable.par_mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
          _modUnionTable.mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
static inline size_t percent_of_space(Space* space, HeapWord* addr)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
  size_t delta = pointer_delta(addr, space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
  return (size_t)(delta * 100.0 / (space->capacity() / HeapWordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
void CMSCollector::icms_update_allocation_limits()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
  Generation* gen0 = GenCollectedHeap::heap()->get_gen(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
  EdenSpace* eden = gen0->as_DefNewGeneration()->eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
  const unsigned int duty_cycle = stats().icms_update_duty_cycle();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
  if (CMSTraceIncrementalPacing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
    stats().print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
  assert(duty_cycle <= 100, "invalid duty cycle");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
  if (duty_cycle != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
    // The duty_cycle is a percentage between 0 and 100; convert to words and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
    // then compute the offset from the endpoints of the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
    size_t free_words = eden->free() / HeapWordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
    double free_words_dbl = (double)free_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
    size_t duty_cycle_words = (size_t)(free_words_dbl * duty_cycle / 100.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
    size_t offset_words = (free_words - duty_cycle_words) / 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
    _icms_start_limit = eden->top() + offset_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
    _icms_stop_limit = eden->end() - offset_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
    // The limits may be adjusted (shifted to the right) by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
    // CMSIncrementalOffset, to allow the application more mutator time after a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
    // young gen gc (when all mutators were stopped) and before CMS starts and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
    // takes away one or more cpus.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
    if (CMSIncrementalOffset != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
      double adjustment_dbl = free_words_dbl * CMSIncrementalOffset / 100.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
      size_t adjustment = (size_t)adjustment_dbl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
      HeapWord* tmp_stop = _icms_stop_limit + adjustment;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
      if (tmp_stop > _icms_stop_limit && tmp_stop < eden->end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
        _icms_start_limit += adjustment;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
        _icms_stop_limit = tmp_stop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
  if (duty_cycle == 0 || (_icms_start_limit == _icms_stop_limit)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
    _icms_start_limit = _icms_stop_limit = eden->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
  // Install the new start limit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
  eden->set_soft_end(_icms_start_limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
  if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
    gclog_or_tty->print(" icms alloc limits:  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
                           PTR_FORMAT "," PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
                           " (" SIZE_FORMAT "%%," SIZE_FORMAT "%%) ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
                           _icms_start_limit, _icms_stop_limit,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
                           percent_of_space(eden, _icms_start_limit),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
                           percent_of_space(eden, _icms_stop_limit));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
    if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
      gclog_or_tty->print("eden:  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
      eden->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
// Any changes here should try to maintain the invariant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
// that if this method is called with _icms_start_limit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
// and _icms_stop_limit both NULL, then it should return NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
// and not notify the icms thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
CMSCollector::allocation_limit_reached(Space* space, HeapWord* top,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
                                       size_t word_size)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
  // A start_limit equal to end() means the duty cycle is 0, so treat that as a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
  // nop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
  if (CMSIncrementalMode && _icms_start_limit != space->end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
    if (top <= _icms_start_limit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
      if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
        space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
        gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
        gclog_or_tty->print_cr(" start limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
                               ", new limit=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
                               " (" SIZE_FORMAT "%%)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
                               top, _icms_stop_limit,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
                               percent_of_space(space, _icms_stop_limit));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
      ConcurrentMarkSweepThread::start_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
      assert(top < _icms_stop_limit, "Tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
      if (word_size < pointer_delta(_icms_stop_limit, top)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
        return _icms_stop_limit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
      // The allocation will cross both the _start and _stop limits, so do the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
      // stop notification also and return end().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
      if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
        space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
        gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
        gclog_or_tty->print_cr(" +stop limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
                               ", new limit=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
                               " (" SIZE_FORMAT "%%)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1241
                               top, space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
                               percent_of_space(space, space->end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
      ConcurrentMarkSweepThread::stop_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
      return space->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
    if (top <= _icms_stop_limit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
      if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
        space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
        gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
        gclog_or_tty->print_cr(" stop limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
                               ", new limit=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
                               " (" SIZE_FORMAT "%%)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
                               top, space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
                               percent_of_space(space, space->end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
      ConcurrentMarkSweepThread::stop_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
      return space->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
    if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
      space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
      gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
      gclog_or_tty->print_cr(" end limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
                             ", new limit=" PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
                             top, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  1274
oop ConcurrentMarkSweepGeneration::promote(oop obj, size_t obj_size) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
  assert(obj_size == (size_t)obj->size(), "bad obj_size passed in");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
  // allocate, copy and if necessary update promoinfo --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
  // delegate to underlying space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
  if (Universe::heap()->promotion_should_fail()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
#endif  // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  1286
  oop res = _cmsSpace->promote(obj, obj_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
  if (res == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
    // expand and retry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
    size_t s = _cmsSpace->expansionSpaceRequired(obj_size);  // HeapWords
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
    expand(s*HeapWordSize, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
      CMSExpansionCause::_satisfy_promotion);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
    // Since there's currently no next generation, we don't try to promote
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
    // into a more senior generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
    assert(next_gen() == NULL, "assumption, based upon which no attempt "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
                               "is made to pass on a possibly failing "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
                               "promotion to next generation");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  1297
    res = _cmsSpace->promote(obj, obj_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
  if (res != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
    // See comment in allocate() about when objects should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
    // be allocated live.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
    assert(obj->is_oop(), "Will dereference klass pointer below");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
    collector()->promoted(false,           // Not parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
                          (HeapWord*)res, obj->is_objArray(), obj_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
    // promotion counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
      _numObjectsPromoted++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
      _numWordsPromoted +=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
        (int)(CompactibleFreeListSpace::adjustObjectSize(obj->size()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
ConcurrentMarkSweepGeneration::allocation_limit_reached(Space* space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
                                             HeapWord* top,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
                                             size_t word_sz)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
  return collector()->allocation_limit_reached(space, top, word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1324
// 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
  1325
// ---------------------------------------------------
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1326
// 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
  1327
// 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
  1328
// 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
  1329
// 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
  1330
// be accurately determined.
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1331
// 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
  1332
// -----------------------------------------------------
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1333
// 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
  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 && klass_word & 0 == 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 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
  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
// STATE IDENTIFICATION: (64 bit+COOPS)
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1342
// ------------------------------------
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1343
// 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
  1344
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1345
// 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
  1346
//            obj->size() computes correct size
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1347
//            [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
  1348
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1349
// 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
  1350
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1351
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1352
// STATE TRANSITION DIAGRAM
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1353
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1354
//        mut / parnew                     mut  /  parnew
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1355
// FREE --------------------> TRANSIENT ---------------------> OBJECT --|
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1356
//  ^                                                                   |
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1357
//  |------------------------ DEAD <------------------------------------|
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1358
//         sweep                            mut
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1359
//
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1360
// 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
  1361
// 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
  1362
// 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
  1363
// 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
  1364
// 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
  1365
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
// Things to support parallel young-gen collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
ConcurrentMarkSweepGeneration::par_promote(int thread_num,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
                                           oop old, markOop m,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
                                           size_t word_sz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
  if (Universe::heap()->promotion_should_fail()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
#endif  // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
  CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
  PromotionInfo* promoInfo = &ps->promo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
  // if we are tracking promotions, then first ensure space for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
  // promotion (including spooling space for saving header if necessary).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
  // then allocate and copy, then track promoted info if needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
  // When tracking (see PromotionInfo::track()), the mark word may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
  // be displaced and in this case restoration of the mark word
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
  // occurs in the (oop_since_save_marks_)iterate phase.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
  if (promoInfo->tracking() && !promoInfo->ensure_spooling_space()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
    // Out of space for allocating spooling buffers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
    // try expanding and allocating spooling buffers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
    if (!expand_and_ensure_spooling_space(promoInfo)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
  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
  1393
  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
  1394
  HeapWord* obj_ptr = ps->lab.alloc(alloc_sz);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
  if (obj_ptr == NULL) {
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1396
     obj_ptr = expand_and_par_lab_allocate(ps, alloc_sz);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
     if (obj_ptr == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
       return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
  oop obj = oop(obj_ptr);
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1402
  OrderAccess::storestore();
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1403
  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
  1404
  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
  1405
  // IMPORTANT: See note on object initialization for CMS above.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
  // Otherwise, copy the object.  Here we must be careful to insert the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
  // 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
  1408
  // Except with compressed oops it's the mark word.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
  HeapWord* old_ptr = (HeapWord*)old;
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1410
  // Restore the mark word copied above.
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1411
  obj->set_mark(m);
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1412
  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
  1413
  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
  1414
  OrderAccess::storestore();
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1415
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1416
  if (UseCompressedOops) {
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1417
    // 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
  1418
    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
  1419
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
  if (word_sz > (size_t)oopDesc::header_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
    Copy::aligned_disjoint_words(old_ptr + oopDesc::header_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
                                 obj_ptr + oopDesc::header_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
                                 word_sz - oopDesc::header_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
  }
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1425
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
  // 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
  1427
  // to delay the transition from uninitialized to full object
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
  // (i.e., insertion of klass pointer) until after, so that it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
  // atomically becomes a promoted object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
  if (promoInfo->tracking()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
    promoInfo->track((PromotedObject*)obj, old->klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
  }
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1433
  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
  1434
  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
  1435
  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
  1436
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1437
  // 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
  1438
  OrderAccess::storestore();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
  obj->set_klass(old->klass());
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1440
  // 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
  1441
  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
  1442
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
  collector()->promoted(true,          // parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
                        obj_ptr, old->is_objArray(), word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
  NOT_PRODUCT(
6258
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1447
    Atomic::inc_ptr(&_numObjectsPromoted);
68f252c6e825 6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
ysr
parents: 6246
diff changeset
  1448
    Atomic::add_ptr(alloc_sz, &_numWordsPromoted);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
  return obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
ConcurrentMarkSweepGeneration::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
par_promote_alloc_undo(int thread_num,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
                       HeapWord* obj, size_t word_sz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
  // CMS does not support promotion undo.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
  ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
ConcurrentMarkSweepGeneration::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
par_promote_alloc_done(int thread_num) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
  CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  1466
  ps->lab.retire(thread_num);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
ConcurrentMarkSweepGeneration::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
par_oop_since_save_marks_iterate_done(int thread_num) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
  CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
  ParScanWithoutBarrierClosure* dummy_cl = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
  ps->promo.promoted_oops_iterate_nv(dummy_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
// XXXPERM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
bool ConcurrentMarkSweepGeneration::should_collect(bool   full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
                                                   size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
                                                   bool   tlab)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
  // We allow a STW collection only if a full
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
  // collection was requested.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
  return full || should_allocate(size, tlab); // FIX ME !!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
  // This and promotion failure handling are connected at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
  // hip and should be fixed by untying them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
bool CMSCollector::shouldConcurrentCollect() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
  if (_full_gc_requested) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
      gclog_or_tty->print_cr("CMSCollector: collect because of explicit "
5433
c182d4c3039e 6919638: CMS: ExplicitGCInvokesConcurrent misinteracts with gc locker
ysr
parents: 5431
diff changeset
  1493
                             " gc request (or gc_locker)");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
  // For debugging purposes, change the type of collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1499
  // If the rotation is not on the concurrent collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
  // type, don't start a concurrent collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1501
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
    if (RotateCMSCollectionTypes &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
        (_cmsGen->debug_collection_type() !=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
          ConcurrentMarkSweepGeneration::Concurrent_collection_type)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
      assert(_cmsGen->debug_collection_type() !=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
        ConcurrentMarkSweepGeneration::Unknown_collection_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
        "Bad cms collection type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
  FreelistLocker x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
  // ------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1514
  // Print out lots of information which affects the initiation of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1515
  // a collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
  if (PrintCMSInitiationStatistics && stats().valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
    gclog_or_tty->print("CMSCollector shouldConcurrentCollect: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1518
    gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1519
    gclog_or_tty->print_cr("");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1520
    stats().print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1521
    gclog_or_tty->print_cr("time_until_cms_gen_full %3.7f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1522
      stats().time_until_cms_gen_full());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1523
    gclog_or_tty->print_cr("free="SIZE_FORMAT, _cmsGen->free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1524
    gclog_or_tty->print_cr("contiguous_available="SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1525
                           _cmsGen->contiguous_available());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
    gclog_or_tty->print_cr("promotion_rate=%g", stats().promotion_rate());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
    gclog_or_tty->print_cr("cms_allocation_rate=%g", stats().cms_allocation_rate());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
    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
  1529
    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
  1530
    gclog_or_tty->print_cr("initiatingPermOccupancy=%3.7f", _permGen->initiating_occupancy());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
  // ------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
  // If the estimated time to complete a cms collection (cms_duration())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
  // is less than the estimated time remaining until the cms generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
  // is full, start a collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
  if (!UseCMSInitiatingOccupancyOnly) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
    if (stats().valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
      if (stats().time_until_cms_start() == 0.0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1540
        return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
      // We want to conservatively collect somewhat early in order
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
      // to try and "bootstrap" our CMS/promotion statistics;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
      // this branch will not fire after the first successful CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
      // collection because the stats should then be valid.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
      if (_cmsGen->occupancy() >= _bootstrap_occupancy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
        if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
          gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
            " CMSCollector: collect for bootstrapping statistics:"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
            " occupancy = %f, boot occupancy = %f", _cmsGen->occupancy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
            _bootstrap_occupancy);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
        return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
  // Otherwise, we start a collection cycle if either the perm gen or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
  // old gen want a collection cycle started. Each may use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
  // an appropriate criterion for making this decision.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
  // 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
  1563
  // 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
  1564
  if (_cmsGen->should_concurrent_collect()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
      gclog_or_tty->print_cr("CMS old gen initiated");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1571
  // 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
  1572
  // 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
  1573
  // late anyway.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1574
  GenCollectedHeap* gch = GenCollectedHeap::heap();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1575
  assert(gch->collector_policy()->is_two_generation_policy(),
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1576
         "You may want to check the correctness of the following");
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1577
  if (gch->incremental_collection_will_fail()) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1578
    if (PrintGCDetails && Verbose) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1579
      gclog_or_tty->print("CMSCollector: collect because incremental collection will fail ");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1580
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1581
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1582
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1584
  if (CMSClassUnloadingEnabled && _permGen->should_concurrent_collect()) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1585
    bool res = update_should_unload_classes();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1586
    if (res) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1587
      if (Verbose && PrintGCDetails) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1588
        gclog_or_tty->print_cr("CMS perm gen initiated");
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1589
      }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1590
      return true;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1591
    }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1592
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1593
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
// Clear _expansion_cause fields of constituent generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
void CMSCollector::clear_expansion_cause() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
  _cmsGen->clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
  _permGen->clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1602
// 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
  1603
// 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
  1604
// 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
  1605
// 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
  1606
// 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
  1607
// UseCMSInitiatingOccupancyOnly.  This also has the advantage of
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1608
// 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
  1609
// collections.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1610
// 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
  1611
// conditions hold:
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1612
// . our current occupancy exceeds the configured initiating occupancy
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1613
//   for this generation, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1614
// . 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
  1615
//   expansion, done a collection of this generation, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1616
// . 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
  1617
//   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
  1618
//   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
  1619
//   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
  1620
//   the generation, etc... or ...
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1621
// [.(currently done by CMSCollector::shouldConcurrentCollect() only for
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1622
//   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
  1623
//   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
  1624
//   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
  1625
bool ConcurrentMarkSweepGeneration::should_concurrent_collect() const {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1626
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
  assert_lock_strong(freelistLock());
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1628
  if (occupancy() > initiating_occupancy()) {
1
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 of occupancy %f / %f  ",
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1631
        short_name(), occupancy(), initiating_occupancy());
1
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
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
  if (UseCMSInitiatingOccupancyOnly) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1637
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1638
  if (expansion_cause() == CMSExpansionCause::_satisfy_allocation) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
      gclog_or_tty->print(" %s: collect because expanded for allocation ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
        short_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1644
  }
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1645
  if (_cmsSpace->should_concurrent_collect()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
    if (PrintGCDetails && Verbose) {
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1647
      gclog_or_tty->print(" %s: collect because cmsSpace says so ",
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
        short_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1650
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1651
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1652
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1653
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1654
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1655
void ConcurrentMarkSweepGeneration::collect(bool   full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1656
                                            bool   clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
                                            size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1658
                                            bool   tlab)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
  collector()->collect(full, clear_all_soft_refs, size, tlab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1661
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
void CMSCollector::collect(bool   full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
                           bool   clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
                           size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
                           bool   tlab)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
  if (!UseCMSCollectionPassing && _collectorState > Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1669
    // For debugging purposes skip the collection if the state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
    // is not currently idle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
      gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " skipped full:%d CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
        Thread::current(), full, _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
  // The following "if" branch is present for defensive reasons.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
  // In the current uses of this interface, it can be replaced with:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
  // assert(!GC_locker.is_active(), "Can't be called otherwise");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
  // But I am not placing that assert here to allow future
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
  // generality in invoking this interface.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
  if (GC_locker::is_active()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
    // A consistency test for GC_locker
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
    assert(GC_locker::needs_gc(), "Should have been set already");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
    // Skip this foreground collection, instead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
    // expanding the heap if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
    // Need the free list locks for the call to free() in compute_new_size()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
    compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
  acquire_control_and_collect(full, clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
  _full_gcs_since_conc_gc++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
void CMSCollector::request_full_gc(unsigned int full_gc_count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
  unsigned int gc_count = gch->total_full_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
  if (gc_count == full_gc_count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
    MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
    _full_gc_requested = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
    CGC_lock->notify();   // nudge CMS thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
// The foreground and background collectors need to coordinate in order
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
// to make sure that they do not mutually interfere with CMS collections.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
// When a background collection is active,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
// the foreground collector may need to take over (preempt) and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
// synchronously complete an ongoing collection. Depending on the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
// frequency of the background collections and the heap usage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1714
// of the application, this preemption can be seldom or frequent.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
// There are only certain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
// points in the background collection that the "collection-baton"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1717
// can be passed to the foreground collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
// The foreground collector will wait for the baton before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
// starting any part of the collection.  The foreground collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
// will only wait at one location.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
// The background collector will yield the baton before starting a new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
// phase of the collection (e.g., before initial marking, marking from roots,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
// precleaning, final re-mark, sweep etc.)  This is normally done at the head
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
// of the loop which switches the phases. The background collector does some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
// of the phases (initial mark, final re-mark) with the world stopped.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
// Because of locking involved in stopping the world,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
// the foreground collector should not block waiting for the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
// collector when it is doing a stop-the-world phase.  The background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
// collector will yield the baton at an additional point just before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
// it enters a stop-the-world phase.  Once the world is stopped, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
// background collector checks the phase of the collection.  If the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
// phase has not changed, it proceeds with the collection.  If the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
// phase has changed, it skips that phase of the collection.  See
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
// the comments on the use of the Heap_lock in collect_in_background().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
// Variable used in baton passing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
//   _foregroundGCIsActive - Set to true by the foreground collector when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
//      it wants the baton.  The foreground clears it when it has finished
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
//      the collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
//   _foregroundGCShouldWait - Set to true by the background collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
//        when it is running.  The foreground collector waits while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
//      _foregroundGCShouldWait is true.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
//  CGC_lock - monitor used to protect access to the above variables
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
//      and to notify the foreground and background collectors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
//  _collectorState - current state of the CMS collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
// The foreground collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
//   acquires the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
//   sets _foregroundGCIsActive
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
//   waits on the CGC_lock for _foregroundGCShouldWait to be false
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
//     various locks acquired in preparation for the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
//     are released so as not to block the background collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
//     that is in the midst of a collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
//   proceeds with the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
//   clears _foregroundGCIsActive
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
//   returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
// The background collector in a loop iterating on the phases of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
//      collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
//   acquires the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
//   sets _foregroundGCShouldWait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
//   if _foregroundGCIsActive is set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
//     clears _foregroundGCShouldWait, notifies _CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
//     waits on _CGC_lock for _foregroundGCIsActive to become false
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
//     and exits the loop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
//   otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
//     proceed with that phase of the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
//     if the phase is a stop-the-world phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
//       yield the baton once more just before enqueueing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
//       the stop-world CMS operation (executed by the VM thread).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
//   returns after all phases of the collection are done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1774
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1775
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1776
void CMSCollector::acquire_control_and_collect(bool full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
        bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
  assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1779
  assert(!Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1780
         "shouldn't try to acquire control from self!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
  // Start the protocol for acquiring control of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1783
  // collection from the background collector (aka CMS thread).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1784
  assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1785
         "VM thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
  // Remember the possibly interrupted state of an ongoing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1787
  // concurrent collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1788
  CollectorState first_state = _collectorState;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1789
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1790
  // Signal to a possibly ongoing concurrent collection that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
  // we want to do a foreground collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
  _foregroundGCIsActive = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
  // Disable incremental mode during a foreground collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
  ICMSDisabler icms_disabler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
  // release locks and wait for a notify from the background collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
  // releasing the locks in only necessary for phases which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1799
  // do yields to improve the granularity of the collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
  // We need to lock the Free list lock for the space that we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
  // currently collecting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
  assert(haveFreelistLocks(), "Must be holding free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1804
  bitMapLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1805
  releaseFreelistLocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1806
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
    if (_foregroundGCShouldWait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
      // We are going to be waiting for action for the CMS thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
      // it had better not be gone (for instance at shutdown)!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
      assert(ConcurrentMarkSweepThread::cmst() != NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
             "CMS thread must be running");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
      // Wait here until the background collector gives us the go-ahead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
      ConcurrentMarkSweepThread::clear_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
        ConcurrentMarkSweepThread::CMS_vm_has_token);  // release token
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
      // Get a possibly blocked CMS thread going:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
      //   Note that we set _foregroundGCIsActive true above,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
      //   without protection of the CGC_lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1819
      CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1820
      assert(!ConcurrentMarkSweepThread::vm_thread_wants_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1821
             "Possible deadlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
      while (_foregroundGCShouldWait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
        // wait for notification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
        CGC_lock->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1825
        // Possibility of delay/starvation here, since CMS token does
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
        // not know to give priority to VM thread? Actually, i think
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
        // there wouldn't be any delay/starvation, but the proof of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1828
        // that "fact" (?) appears non-trivial. XXX 20011219YSR
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
      ConcurrentMarkSweepThread::set_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1831
        ConcurrentMarkSweepThread::CMS_vm_has_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1832
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1833
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1834
  // The CMS_token is already held.  Get back the other locks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1835
  assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1836
         "VM thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1837
  getFreelistLocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
  bitMapLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
    gclog_or_tty->print_cr("CMS foreground collector has asked for control "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
      INTPTR_FORMAT " with first state %d", Thread::current(), first_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
    gclog_or_tty->print_cr("    gets control with state %d", _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
  // Check if we need to do a compaction, or if not, whether
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
  // we need to start the mark-sweep from scratch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
  bool should_compact    = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1848
  bool should_start_over = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
  decide_foreground_collection_type(clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1850
    &should_compact, &should_start_over);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1851
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
  if (RotateCMSCollectionTypes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1854
    if (_cmsGen->debug_collection_type() ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1855
        ConcurrentMarkSweepGeneration::MSC_foreground_collection_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1856
      should_compact = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1857
    } else if (_cmsGen->debug_collection_type() ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1858
               ConcurrentMarkSweepGeneration::MS_foreground_collection_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1859
      should_compact = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1860
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1861
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1862
)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1863
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1864
  if (PrintGCDetails && first_state > Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1865
    GCCause::Cause cause = GenCollectedHeap::heap()->gc_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1866
    if (GCCause::is_user_requested_gc(cause) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1867
        GCCause::is_serviceability_requested_gc(cause)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
      gclog_or_tty->print(" (concurrent mode interrupted)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
      gclog_or_tty->print(" (concurrent mode failure)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1872
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
  if (should_compact) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1875
    // If the collection is being acquired from the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1876
    // collector, there may be references on the discovered
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1877
    // references lists that have NULL referents (being those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1878
    // that were concurrently cleared by a mutator) or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1879
    // that are no longer active (having been enqueued concurrently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1880
    // by the mutator).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1881
    // Scrub the list of those references because Mark-Sweep-Compact
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1882
    // code assumes referents are not NULL and that all discovered
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1883
    // Reference objects are active.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1884
    ref_processor()->clean_up_discovered_references();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1885
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1886
    do_compaction_work(clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1887
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1888
    // 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
  1889
    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
  1890
    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
  1891
                           young_gen->to()->capacity() -
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1892
                           young_gen->from()->capacity();
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1893
    GenCollectedHeap* gch = GenCollectedHeap::heap();
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1894
    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
  1895
    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
  1896
                                           young_gen->eden()->used(),
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1897
                                           _cmsGen->max_capacity(),
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1898
                                           max_eden_size,
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1899
                                           full,
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1900
                                           gc_cause,
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  1901
                                           gch->collector_policy());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
    do_mark_sweep_work(clear_all_soft_refs, first_state,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
      should_start_over);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
  // Reset the expansion cause, now that we just completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
  // a collection cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
  clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
  _foregroundGCIsActive = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
// Resize the perm generation and the tenured generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
// after obtaining the free list locks for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
// two generations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
void CMSCollector::compute_new_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
  FreelistLocker z(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
  _permGen->compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
  _cmsGen->compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
// A work method used by foreground collection to determine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
// what type of collection (compacting or not, continuing or fresh)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
// it should do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
// NOTE: the intent is to make UseCMSCompactAtFullCollection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
// and CMSCompactWhenClearAllSoftRefs the default in the future
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
// and do away with the flags after a suitable period.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
void CMSCollector::decide_foreground_collection_type(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
  bool clear_all_soft_refs, bool* should_compact,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
  bool* should_start_over) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
  // Normally, we'll compact only if the UseCMSCompactAtFullCollection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
  // flag is set, and we have either requested a System.gc() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
  // the number of full gc's since the last concurrent cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
  // has exceeded the threshold set by CMSFullGCsBeforeCompaction,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
  // or if an incremental collection has failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
  assert(gch->collector_policy()->is_two_generation_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
         "You may want to check the correctness of the following");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
  // Inform cms gen if this was due to partial collection failing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
  // The CMS gen may use this fact to determine its expansion policy.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
  if (gch->incremental_collection_will_fail()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
    assert(!_cmsGen->incremental_collection_failed(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
           "Should have been noticed, reacted to and cleared");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
    _cmsGen->set_incremental_collection_failed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
  *should_compact =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
    UseCMSCompactAtFullCollection &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
    ((_full_gcs_since_conc_gc >= CMSFullGCsBeforeCompaction) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
     GCCause::is_user_requested_gc(gch->gc_cause()) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
     gch->incremental_collection_will_fail());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
  *should_start_over = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
  if (clear_all_soft_refs && !*should_compact) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
    // We are about to do a last ditch collection attempt
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
    // so it would normally make sense to do a compaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
    // to reclaim as much space as possible.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1957
    if (CMSCompactWhenClearAllSoftRefs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1958
      // Default: The rationale is that in this case either
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1959
      // we are past the final marking phase, in which case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
      // we'd have to start over, or so little has been done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1961
      // that there's little point in saving that work. Compaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1962
      // appears to be the sensible choice in either case.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1963
      *should_compact = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1964
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1965
      // We have been asked to clear all soft refs, but not to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1966
      // compact. Make sure that we aren't past the final checkpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
      // phase, for that is where we process soft refs. If we are already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1968
      // past that phase, we'll need to redo the refs discovery phase and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1969
      // if necessary clear soft refs that weren't previously
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
      // cleared. We do so by remembering the phase in which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
      // we came in, and if we are past the refs processing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
      // phase, we'll choose to just redo the mark-sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1973
      // collection from scratch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
      if (_collectorState > FinalMarking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
        // We are past the refs processing phase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
        // start over and do a fresh synchronous CMS cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
        _collectorState = Resetting; // skip to reset to start new cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1978
        reset(false /* == !asynch */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1979
        *should_start_over = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
      } // else we can continue a possibly ongoing current cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1981
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1982
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1983
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1984
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1985
// A work method used by the foreground collector to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1986
// a mark-sweep-compact.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1987
void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1988
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1989
  TraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1990
  if (PrintGC && Verbose && !(GCCause::is_user_requested_gc(gch->gc_cause()))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1991
    gclog_or_tty->print_cr("Compact ConcurrentMarkSweepGeneration after %d "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1992
      "collections passed to foreground collector", _full_gcs_since_conc_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1993
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1994
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1995
  // Sample collection interval time and reset for collection pause.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1996
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1997
    size_policy()->msc_collection_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1998
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1999
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2000
  // Temporarily widen the span of the weak reference processing to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2001
  // the entire heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2002
  MemRegion new_span(GenCollectedHeap::heap()->reserved_region());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2003
  ReferenceProcessorSpanMutator x(ref_processor(), new_span);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2004
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2005
  // Temporarily, clear the "is_alive_non_header" field of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
  // reference processor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
  ReferenceProcessorIsAliveMutator y(ref_processor(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
  // Temporarily make reference _processing_ single threaded (non-MT).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
  ReferenceProcessorMTProcMutator z(ref_processor(), false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
  // Temporarily make refs discovery atomic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
  ReferenceProcessorAtomicMutator w(ref_processor(), true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
  ref_processor()->set_enqueuing_is_done(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
  ref_processor()->enable_discovery();
1610
5dddd195cc86 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 1606
diff changeset
  2017
  ref_processor()->setup_policy(clear_all_soft_refs);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
  // If an asynchronous collection finishes, the _modUnionTable is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
  // all clear.  If we are assuming the collection from an asynchronous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
  // collection, clear the _modUnionTable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2021
  assert(_collectorState != Idling || _modUnionTable.isAllClear(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
    "_modUnionTable should be clear if the baton was not passed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
  _modUnionTable.clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2024
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
  // We must adjust the allocation statistics being maintained
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
  // in the free list space. We do so by reading and clearing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
  // 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
  2028
  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
  2029
  if (_inter_sweep_timer.is_active()) {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2030
    _inter_sweep_timer.stop();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2031
    // 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
  2032
    _cmsGen->cmsSpace()->beginSweepFLCensus((float)(_inter_sweep_timer.seconds()),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2033
                                            _inter_sweep_estimate.padded_average(),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2034
                                            _intra_sweep_estimate.padded_average());
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2035
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
6245
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  2037
  {
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  2038
    TraceCMSMemoryManagerStats();
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  2039
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2040
  GenMarkSweep::invoke_at_safepoint(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
    ref_processor(), clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2042
  #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2043
    CompactibleFreeListSpace* cms_space = _cmsGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
    size_t free_size = cms_space->free();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
    assert(free_size ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
           pointer_delta(cms_space->end(), cms_space->compaction_top())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2047
           * HeapWordSize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
      "All the free space should be compacted into one chunk at top");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
    assert(cms_space->dictionary()->totalChunkSize(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
                                      debug_only(cms_space->freelistLock())) == 0 ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
           cms_space->totalSizeInIndexedFreeLists() == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2052
      "All the free space should be in a single chunk");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2053
    size_t num = cms_space->totalCount();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2054
    assert((free_size == 0 && num == 0) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2055
           (free_size > 0  && (num == 1 || num == 2)),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2056
         "There should be at most 2 free chunks after compaction");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2057
  #endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2058
  _collectorState = Resetting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2059
  assert(_restart_addr == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2060
         "Should have been NULL'd before baton was passed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2061
  reset(false /* == !asynch */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2062
  _cmsGen->reset_after_compaction();
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2063
  _concurrent_cycles_since_last_unload = 0;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2064
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2065
  if (verifying() && !should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2066
    perm_gen_verify_bit_map()->clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2067
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2068
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2069
  // Clear any data recorded in the PLAB chunk arrays.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2070
  if (_survivor_plab_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2071
    reset_survivor_plab_arrays();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2072
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2073
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2074
  // Adjust the per-size allocation stats for the next epoch.
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2075
  _cmsGen->cmsSpace()->endSweepFLCensus(sweep_count() /* fake */);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2076
  // Restart the "inter sweep timer" for the next epoch.
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2077
  _inter_sweep_timer.reset();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2078
  _inter_sweep_timer.start();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2079
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2080
  // Sample collection pause time and reset for collection interval.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2081
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2082
    size_policy()->msc_collection_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2083
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2084
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2085
  // For a mark-sweep-compact, compute_new_size() will be called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2086
  // in the heap's do_collection() method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2087
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2088
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2089
// A work method used by the foreground collector to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2090
// a mark-sweep, after taking over from a possibly on-going
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2091
// concurrent mark-sweep collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2092
void CMSCollector::do_mark_sweep_work(bool clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2093
  CollectorState first_state, bool should_start_over) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2094
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2095
    gclog_or_tty->print_cr("Pass concurrent collection to foreground "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2096
      "collector with count %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2097
      _full_gcs_since_conc_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2098
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2099
  switch (_collectorState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2100
    case Idling:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2101
      if (first_state == Idling || should_start_over) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2102
        // The background GC was not active, or should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2103
        // restarted from scratch;  start the cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2104
        _collectorState = InitialMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2106
      // If first_state was not Idling, then a background GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2107
      // was in progress and has now finished.  No need to do it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
      // again.  Leave the state as Idling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
    case Precleaning:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
      // In the foreground case don't do the precleaning since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
      // it is not done concurrently and there is extra work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
      // required.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2114
      _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
  if (PrintGCDetails &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
      (_collectorState > Idling ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2118
       !GCCause::is_user_requested_gc(GenCollectedHeap::heap()->gc_cause()))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
    gclog_or_tty->print(" (concurrent mode failure)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
  collect_in_foreground(clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
  // For a mark-sweep, compute_new_size() will be called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
  // in the heap's do_collection() method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
void CMSCollector::getFreelistLocks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
  // Get locks for all free lists in all generations that this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
  // collector is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
  _cmsGen->freelistLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
  _permGen->freelistLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2133
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2134
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
void CMSCollector::releaseFreelistLocks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2136
  // Release locks for all free lists in all generations that this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2137
  // collector is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2138
  _cmsGen->freelistLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2139
  _permGen->freelistLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2140
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2141
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2142
bool CMSCollector::haveFreelistLocks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2143
  // Check locks for all free lists in all generations that this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2144
  // collector is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2145
  assert_lock_strong(_cmsGen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2146
  assert_lock_strong(_permGen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2147
  PRODUCT_ONLY(ShouldNotReachHere());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2148
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2149
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2150
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2151
// A utility class that is used by the CMS collector to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2152
// temporarily "release" the foreground collector from its
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2153
// usual obligation to wait for the background collector to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2154
// complete an ongoing phase before proceeding.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2155
class ReleaseForegroundGC: public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2156
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2157
  CMSCollector* _c;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2158
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2159
  ReleaseForegroundGC(CMSCollector* c) : _c(c) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2160
    assert(_c->_foregroundGCShouldWait, "Else should not need to call");
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
    // allow a potentially blocked foreground collector to proceed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2163
    _c->_foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2164
    if (_c->_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2165
      CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2166
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2167
    assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2168
           "Possible deadlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2169
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2170
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2171
  ~ReleaseForegroundGC() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2172
    assert(!_c->_foregroundGCShouldWait, "Usage protocol violation?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
    _c->_foregroundGCShouldWait = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
// There are separate collect_in_background and collect_in_foreground because of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2179
// the different locking requirements of the background collector and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2180
// foreground collector.  There was originally an attempt to share
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2181
// one "collect" method between the background collector and the foreground
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
// collector but the if-then-else required made it cleaner to have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
// separate methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
void CMSCollector::collect_in_background(bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2185
  assert(Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2186
    "A CMS asynchronous collection is only allowed on a CMS thread.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2187
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2189
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
    bool safepoint_check = Mutex::_no_safepoint_check_flag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
    MutexLockerEx hl(Heap_lock, safepoint_check);
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2192
    FreelistLocker fll(this);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
    MutexLockerEx x(CGC_lock, safepoint_check);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
    if (_foregroundGCIsActive || !UseAsyncConcMarkSweepGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2195
      // The foreground collector is active or we're
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2196
      // not using asynchronous collections.  Skip this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2197
      // background collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2198
      assert(!_foregroundGCShouldWait, "Should be clear");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2199
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2200
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2201
      assert(_collectorState == Idling, "Should be idling before start.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2202
      _collectorState = InitialMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2203
      // Reset the expansion cause, now that we are about to begin
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
      // a new cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
      clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
    }
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2207
    // 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
  2208
    // ensuing concurrent GC cycle.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2209
    update_should_unload_classes();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
    _full_gc_requested = false;           // acks all outstanding full gc requests
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2211
    // Signal that we are about to start a collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
    gch->increment_total_full_collections();  // ... starting a collection cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
    _collection_count_start = gch->total_full_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
  // Used for PrintGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
  size_t prev_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
    prev_used = _cmsGen->used(); // XXXPERM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
  // The change of the collection state is normally done at this level;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
  // the exceptions are phases that are executed while the world is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2224
  // stopped.  For those phases the change of state is done while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2225
  // world is stopped.  For baton passing purposes this allows the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2226
  // background collector to finish the phase and change state atomically.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2227
  // The foreground collector cannot wait on a phase that is done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2228
  // while the world is stopped because the foreground collector already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2229
  // has the world stopped and would deadlock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2230
  while (_collectorState != Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2231
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2232
      gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " in CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
    // The foreground collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
    //   holds the Heap_lock throughout its collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
    //   holds the CMS token (but not the lock)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
    //     except while it is waiting for the background collector to yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
    // The foreground collector should be blocked (not for long)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
    //   if the background collector is about to start a phase
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
    //   executed with world stopped.  If the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
    //   collector has already started such a phase, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
    //   foreground collector is blocked waiting for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
    //   Heap_lock.  The stop-world phases (InitialMarking and FinalMarking)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
    //   are executed in the VM thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
    // The locking order is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
    //   PendingListLock (PLL)  -- if applicable (FinalMarking)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
    //   Heap_lock  (both this & PLL locked in VM_CMS_Operation::prologue())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
    //   CMS token  (claimed in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
    //                stop_world_and_do() -->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
    //                  safepoint_synchronize() -->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2254
    //                    CMSThread::synchronize())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
      // Check if the FG collector wants us to yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
      CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2259
      if (waitForForegroundGC()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2260
        // We yielded to a foreground GC, nothing more to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2261
        // done this round.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
        assert(_foregroundGCShouldWait == false, "We set it to false in "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
               "waitForForegroundGC()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
        if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
          gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
            " exiting collection CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
            Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
        // The background collector can run but check to see if the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
        // foreground collector has done a collection while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2273
        // background collector was waiting to get the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
        // above.  If yes, break so that _foregroundGCShouldWait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
        // is cleared before returning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
        if (_collectorState == Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
    assert(_foregroundGCShouldWait, "Foreground collector, if active, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
      "should be waiting");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
    switch (_collectorState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2286
      case InitialMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2288
          ReleaseForegroundGC x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
          stats().record_cms_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
          VM_CMS_Initial_Mark initial_mark_op(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
          VMThread::execute(&initial_mark_op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
        // The collector state may be any legal state at this point
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
        // since the background collector may have yielded to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
        // foreground collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
      case Marking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
        // initial marking in checkpointRootsInitialWork has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
        if (markFromRoots(true)) { // we were successful
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
          assert(_collectorState == Precleaning, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
            "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
          assert(_foregroundGCIsActive, "Internal state inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
      case Precleaning:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
          size_policy()->concurrent_precleaning_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
        // marking from roots in markFromRoots has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
        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 == AbortablePreclean ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2317
               _collectorState == FinalMarking,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2318
               "Collector state should have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2320
      case AbortablePreclean:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
        size_policy()->concurrent_phases_resume();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2324
        abortable_preclean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
          size_policy()->concurrent_precleaning_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
        assert(_collectorState == FinalMarking, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
          "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
      case FinalMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
          ReleaseForegroundGC x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2335
          VM_CMS_Final_Remark final_remark_op(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2336
          VMThread::execute(&final_remark_op);
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  2337
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2338
        assert(_foregroundGCShouldWait, "block post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2339
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2340
      case Sweeping:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2341
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
          size_policy()->concurrent_sweeping_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2343
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
        // final marking in checkpointRootsFinal has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
        sweep(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
        assert(_collectorState == Resizing, "Collector state change "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
          "to Resizing must be done under the free_list_lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
        _full_gcs_since_conc_gc = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
        // Stop the timers for adaptive size policy for the concurrent phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
          size_policy()->concurrent_sweeping_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
          size_policy()->concurrent_phases_end(gch->gc_cause(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
                                             gch->prev_gen(_cmsGen)->capacity(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
                                             _cmsGen->free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
      case Resizing: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
        // Sweeping has been completed...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2360
        // At this point the background collection has completed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2361
        // Don't move the call to compute_new_size() down
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2362
        // into code that might be executed if the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2363
        // collection was preempted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2365
          ReleaseForegroundGC x(this);   // unblock FG collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2366
          MutexLockerEx       y(Heap_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2367
          CMSTokenSync        z(true);   // not strictly needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2368
          if (_collectorState == Resizing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2369
            compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2370
            _collectorState = Resetting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2371
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2372
            assert(_collectorState == Idling, "The state should only change"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2373
                   " because the foreground collector has finished the collection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2374
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2375
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2376
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2377
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2378
      case Resetting:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2379
        // CMS heap resizing has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
        reset(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2381
        assert(_collectorState == Idling, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2382
          "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2383
        stats().record_cms_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
        // Don't move the concurrent_phases_end() and compute_new_size()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
        // calls to here because a preempted background collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2386
        // has it's state set to "Resetting".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2387
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2388
      case Idling:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2390
        ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2393
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
      gclog_or_tty->print_cr("  Thread " INTPTR_FORMAT " done - next CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2396
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2397
    assert(_foregroundGCShouldWait, "block post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
  // Should this be in gc_epilogue?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
  collector_policy()->counters()->update_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
    // Clear _foregroundGCShouldWait and, in the event that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
    // foreground collector is waiting, notify it, before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
    // returning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
    _foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2409
    if (_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2410
      CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2411
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2412
    assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
           "Possible deadlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
      " exiting collection CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
      Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
    _cmsGen->print_heap_change(prev_used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
  assert(_foregroundGCIsActive && !_foregroundGCShouldWait,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
         "Foreground collector should be waiting, not executing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
  assert(Thread::current()->is_VM_thread(), "A foreground collection"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
    "may only be done by the VM Thread with the world stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
  assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2431
         "VM thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2432
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2433
  NOT_PRODUCT(TraceTime t("CMS:MS (foreground) ", PrintGCDetails && Verbose,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2434
    true, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2435
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2436
    size_policy()->ms_collection_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2437
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2438
  COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2439
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2440
  HandleMark hm;  // Discard invalid handles created during verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2441
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2442
  if (VerifyBeforeGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2443
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2444
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2445
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2446
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  2447
  // 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
  2448
  ref_processor()->setup_policy(clear_all_soft_refs);
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  2449
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2450
  bool init_mark_was_synchronous = false; // until proven otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2451
  while (_collectorState != Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2452
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2453
      gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " in CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2454
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2455
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2456
    switch (_collectorState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2457
      case InitialMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2458
        init_mark_was_synchronous = true;  // fact to be exploited in re-mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2459
        checkpointRootsInitial(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2460
        assert(_collectorState == Marking, "Collector state should have changed"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2461
          " within checkpointRootsInitial()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2462
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2463
      case Marking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2464
        // initial marking in checkpointRootsInitialWork has been completed
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 initial 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
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2471
          bool res = markFromRoots(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2472
          assert(res && _collectorState == FinalMarking, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2473
            "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2474
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2475
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2476
      case FinalMarking:
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 re-mark: ");
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
        checkpointRootsFinal(false, clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2483
                             init_mark_was_synchronous);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2484
        assert(_collectorState == Sweeping, "Collector state should not "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2485
          "have changed within checkpointRootsFinal()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2486
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2487
      case Sweeping:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2488
        // final marking in checkpointRootsFinal has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2489
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2490
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2491
          gclog_or_tty->print("Verify before sweep: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2492
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2493
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2494
        sweep(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2495
        assert(_collectorState == Resizing, "Incorrect state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2496
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2497
      case Resizing: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2498
        // Sweeping has been completed; the actual resize in this case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2499
        // is done separately; nothing to be done in this state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2500
        _collectorState = Resetting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2501
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2502
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2503
      case Resetting:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2504
        // The heap has been resized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2505
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2506
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2507
          gclog_or_tty->print("Verify before reset: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2508
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2509
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2510
        reset(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2511
        assert(_collectorState == Idling, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
          "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2513
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2514
      case Precleaning:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2515
      case AbortablePreclean:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2516
        // Elide the preclean phase
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
        _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2519
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
        ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2521
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
      gclog_or_tty->print_cr("  Thread " INTPTR_FORMAT " done - next CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2524
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2525
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2526
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2528
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2529
    GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
    size_policy()->ms_collection_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2531
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2533
  if (VerifyAfterGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2534
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2535
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2536
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2537
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
      " exiting collection CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2540
      Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
bool CMSCollector::waitForForegroundGC() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
  bool res = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
         "CMS thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
  // Block the foreground collector until the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
  // background collectors decides whether to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
  // yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2551
  MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2552
  _foregroundGCShouldWait = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2553
  if (_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
    // The background collector yields to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
    // foreground collector and returns a value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2556
    // indicating that it has yielded.  The foreground
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2557
    // collector can proceed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2558
    res = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2559
    _foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2560
    ConcurrentMarkSweepThread::clear_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2561
      ConcurrentMarkSweepThread::CMS_cms_has_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
    ConcurrentMarkSweepThread::set_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
      ConcurrentMarkSweepThread::CMS_cms_wants_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2564
    // Get a possibly blocked foreground thread going
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2565
    CGC_lock->notify();
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 " waiting 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
    while (_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2571
      CGC_lock->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2572
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2573
    ConcurrentMarkSweepThread::set_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2574
      ConcurrentMarkSweepThread::CMS_cms_has_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
    ConcurrentMarkSweepThread::clear_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2576
      ConcurrentMarkSweepThread::CMS_cms_wants_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2579
    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT " continuing at CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2580
      Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
// Because of the need to lock the free lists and other structures in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
// the collector, common to all the generations that the collector is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
// collecting, we need the gc_prologues of individual CMS generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
// delegate to their collector. It may have been simpler had the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
// current infrastructure allowed one to call a prologue on a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2590
// collector. In the absence of that we have the generation's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2591
// prologue delegate to the collector, which delegates back
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2592
// some "local" work to a worker method in the individual generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2593
// that it's responsible for collecting, while itself doing any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2594
// work common to all generations it's responsible for. A similar
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
// comment applies to the  gc_epilogue()'s.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
// The role of the varaible _between_prologue_and_epilogue is to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
// enforce the invocation protocol.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
void CMSCollector::gc_prologue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
  // Call gc_prologue_work() for each CMSGen and PermGen that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
  // we are responsible for.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
  // The following locking discipline assumes that we are only called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
  // when the world is stopped.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2604
  assert(SafepointSynchronize::is_at_safepoint(), "world is stopped assumption");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
  // The CMSCollector prologue must call the gc_prologues for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
  // "generations" (including PermGen if any) that it's responsible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
  // for.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2610
  assert(   Thread::current()->is_VM_thread()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
         || (   CMSScavengeBeforeRemark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
             && Thread::current()->is_ConcurrentGC_thread()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2613
         "Incorrect thread type for prologue execution");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2614
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2615
  if (_between_prologue_and_epilogue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2616
    // We have already been invoked; this is a gc_prologue delegation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2617
    // from yet another CMS generation that we are responsible for, just
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2618
    // ignore it since all relevant work has already been done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2619
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2620
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2621
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2622
  // set a bit saying prologue has been called; cleared in epilogue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2623
  _between_prologue_and_epilogue = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
  // Claim locks for common data structures, then call gc_prologue_work()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
  // for each CMSGen and PermGen that we are responsible for.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2626
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
  getFreelistLocks();   // gets free list locks on constituent spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2628
  bitMapLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2629
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2630
  // Should call gc_prologue_work() for all cms gens we are responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2631
  bool registerClosure =    _collectorState >= Marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
                         && _collectorState < Sweeping;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2633
  ModUnionClosure* muc = ParallelGCThreads > 0 ? &_modUnionClosurePar
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2634
                                               : &_modUnionClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2635
  _cmsGen->gc_prologue_work(full, registerClosure, muc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2636
  _permGen->gc_prologue_work(full, registerClosure, muc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2637
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2638
  if (!full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2639
    stats().record_gc0_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2640
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2641
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2642
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2643
void ConcurrentMarkSweepGeneration::gc_prologue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2644
  // Delegate to CMScollector which knows how to coordinate between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2645
  // this and any other CMS generations that it is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2646
  // collecting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2647
  collector()->gc_prologue(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2648
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2649
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2650
// This is a "private" interface for use by this generation's CMSCollector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2651
// Not to be called directly by any other entity (for instance,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2652
// GenCollectedHeap, which calls the "public" gc_prologue method above).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2653
void ConcurrentMarkSweepGeneration::gc_prologue_work(bool full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2654
  bool registerClosure, ModUnionClosure* modUnionClosure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2655
  assert(!incremental_collection_failed(), "Shouldn't be set yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2656
  assert(cmsSpace()->preconsumptionDirtyCardClosure() == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2657
    "Should be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2658
  if (registerClosure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2659
    cmsSpace()->setPreconsumptionDirtyCardClosure(modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2660
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2661
  cmsSpace()->gc_prologue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2662
  // Clear stat counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2663
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2664
    assert(_numObjectsPromoted == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2665
    assert(_numWordsPromoted   == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2666
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2667
      gclog_or_tty->print("Allocated "SIZE_FORMAT" objects, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2668
                          SIZE_FORMAT" bytes concurrently",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2669
      _numObjectsAllocated, _numWordsAllocated*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2670
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2671
    _numObjectsAllocated = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2672
    _numWordsAllocated   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2673
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2674
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2675
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2676
void CMSCollector::gc_epilogue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2677
  // The following locking discipline assumes that we are only called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2678
  // when the world is stopped.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2679
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2680
         "world is stopped assumption");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2681
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2682
  // Currently the CMS epilogue (see CompactibleFreeListSpace) merely checks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2683
  // if linear allocation blocks need to be appropriately marked to allow the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2684
  // the blocks to be parsable. We also check here whether we need to nudge the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2685
  // CMS collector thread to start a new cycle (if it's not already active).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2686
  assert(   Thread::current()->is_VM_thread()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2687
         || (   CMSScavengeBeforeRemark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2688
             && Thread::current()->is_ConcurrentGC_thread()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2689
         "Incorrect thread type for epilogue execution");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2690
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2691
  if (!_between_prologue_and_epilogue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2692
    // We have already been invoked; this is a gc_epilogue delegation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2693
    // from yet another CMS generation that we are responsible for, just
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2694
    // ignore it since all relevant work has already been done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2695
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2696
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2697
  assert(haveFreelistLocks(), "must have freelist locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2698
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2699
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2700
  _cmsGen->gc_epilogue_work(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2701
  _permGen->gc_epilogue_work(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2702
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2703
  if (_collectorState == AbortablePreclean || _collectorState == Precleaning) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2704
    // in case sampling was not already enabled, enable it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2705
    _start_sampling = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2706
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2707
  // reset _eden_chunk_array so sampling starts afresh
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2708
  _eden_chunk_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2709
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2710
  size_t cms_used   = _cmsGen->cmsSpace()->used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2711
  size_t perm_used  = _permGen->cmsSpace()->used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2712
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2713
  // update performance counters - this uses a special version of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2714
  // update_counters() that allows the utilization to be passed as a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2715
  // parameter, avoiding multiple calls to used().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2716
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2717
  _cmsGen->update_counters(cms_used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2718
  _permGen->update_counters(perm_used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2719
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2720
  if (CMSIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2721
    icms_update_allocation_limits();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2722
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2723
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2724
  bitMapLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2725
  releaseFreelistLocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2726
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2727
  _between_prologue_and_epilogue = false;  // ready for next cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2728
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2729
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2730
void ConcurrentMarkSweepGeneration::gc_epilogue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2731
  collector()->gc_epilogue(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2732
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2733
  // Also reset promotion tracking in par gc thread states.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2734
  if (ParallelGCThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2735
    for (uint i = 0; i < ParallelGCThreads; i++) {
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2736
      _par_gc_thread_states[i]->promo.stopTrackingPromotions(i);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2737
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2738
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2739
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2740
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2741
void ConcurrentMarkSweepGeneration::gc_epilogue_work(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2742
  assert(!incremental_collection_failed(), "Should have been cleared");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2743
  cmsSpace()->setPreconsumptionDirtyCardClosure(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2744
  cmsSpace()->gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2745
    // Print stat counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2746
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2747
    assert(_numObjectsAllocated == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2748
    assert(_numWordsAllocated == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2749
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2750
      gclog_or_tty->print("Promoted "SIZE_FORMAT" objects, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2751
                          SIZE_FORMAT" bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2752
                 _numObjectsPromoted, _numWordsPromoted*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2753
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2754
    _numObjectsPromoted = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2755
    _numWordsPromoted   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2756
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2757
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2758
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2759
    // Call down the chain in contiguous_available needs the freelistLock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2760
    // so print this out before releasing the freeListLock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2761
    gclog_or_tty->print(" Contiguous available "SIZE_FORMAT" bytes ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2762
                        contiguous_available());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2763
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2764
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2765
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2766
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2767
bool CMSCollector::have_cms_token() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2768
  Thread* thr = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2769
  if (thr->is_VM_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2770
    return ConcurrentMarkSweepThread::vm_thread_has_cms_token();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2771
  } else if (thr->is_ConcurrentGC_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2772
    return ConcurrentMarkSweepThread::cms_thread_has_cms_token();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2773
  } else if (thr->is_GC_task_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2774
    return ConcurrentMarkSweepThread::vm_thread_has_cms_token() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2775
           ParGCRareEvent_lock->owned_by_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2776
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2777
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2778
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2779
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2780
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2781
// Check reachability of the given heap address in CMS generation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2782
// treating all other generations as roots.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2783
bool CMSCollector::is_cms_reachable(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2784
  // We could "guarantee" below, rather than assert, but i'll
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2785
  // leave these as "asserts" so that an adventurous debugger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2786
  // could try this in the product build provided some subset of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2787
  // the conditions were met, provided they were intersted in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2788
  // results and knew that the computation below wouldn't interfere
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2789
  // with other concurrent computations mutating the structures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2790
  // being read or written.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2791
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2792
         "Else mutations in object graph will make answer suspect");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2793
  assert(have_cms_token(), "Should hold cms token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2794
  assert(haveFreelistLocks(), "must hold free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2795
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2796
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2797
  // Clear the marking bit map array before starting, but, just
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2798
  // for kicks, first report if the given address is already marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2799
  gclog_or_tty->print_cr("Start: Address 0x%x is%s marked", addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2800
                _markBitMap.isMarked(addr) ? "" : " not");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2801
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2802
  if (verify_after_remark()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2803
    MutexLockerEx x(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2804
    bool result = verification_mark_bm()->isMarked(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2805
    gclog_or_tty->print_cr("TransitiveMark: Address 0x%x %s marked", addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2806
                           result ? "IS" : "is NOT");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2807
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2808
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2809
    gclog_or_tty->print_cr("Could not compute result");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2810
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2811
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2812
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2813
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2814
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2815
// CMS Verification Support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2816
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2817
// Following the remark phase, the following invariant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2818
// should hold -- each object in the CMS heap which is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2819
// marked in markBitMap() should be marked in the verification_mark_bm().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2820
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2821
class VerifyMarkedClosure: public BitMapClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2822
  CMSBitMap* _marks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2823
  bool       _failed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2824
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2825
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2826
  VerifyMarkedClosure(CMSBitMap* bm): _marks(bm), _failed(false) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2827
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  2828
  bool do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2829
    HeapWord* addr = _marks->offsetToHeapWord(offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2830
    if (!_marks->isMarked(addr)) {
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2831
      oop(addr)->print_on(gclog_or_tty);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2832
      gclog_or_tty->print_cr(" ("INTPTR_FORMAT" should have been marked)", addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2833
      _failed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2834
    }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  2835
    return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2836
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2837
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2838
  bool failed() { return _failed; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2839
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2840
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2841
bool CMSCollector::verify_after_remark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2842
  gclog_or_tty->print(" [Verifying CMS Marking... ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2843
  MutexLockerEx ml(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2844
  static bool init = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2845
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2846
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2847
         "Else mutations in object graph will make answer suspect");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2848
  assert(have_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2849
         "Else there may be mutual interference in use of "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2850
         " verification data structures");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2851
  assert(_collectorState > Marking && _collectorState <= Sweeping,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2852
         "Else marking info checked here may be obsolete");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2853
  assert(haveFreelistLocks(), "must hold free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2854
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2855
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2856
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2857
  // Allocate marking bit map if not already allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2858
  if (!init) { // first time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2859
    if (!verification_mark_bm()->allocate(_span)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2860
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2861
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2862
    init = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2863
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2864
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2865
  assert(verification_mark_stack()->isEmpty(), "Should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2866
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2867
  // Turn off refs discovery -- so we will be tracing through refs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2868
  // This is as intended, because by this time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2869
  // GC must already have cleared any refs that need to be cleared,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2870
  // and traced those that need to be marked; moreover,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2871
  // the marking done here is not going to intefere in any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2872
  // way with the marking information used by GC.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2873
  NoRefDiscovery no_discovery(ref_processor());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2874
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2875
  COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2876
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2877
  // Clear any marks from a previous round
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2878
  verification_mark_bm()->clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2879
  assert(verification_mark_stack()->isEmpty(), "markStack should be empty");
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2880
  verify_work_stacks_empty();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2881
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2882
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2883
  gch->ensure_parsability(false);  // fill TLABs, but no need to retire them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2884
  // Update the saved marks which may affect the root scans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2885
  gch->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2886
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2887
  if (CMSRemarkVerifyVariant == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2888
    // In this first variant of verification, we complete
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2889
    // all marking, then check if the new marks-verctor is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2890
    // a subset of the CMS marks-vector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2891
    verify_after_remark_work_1();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2892
  } else if (CMSRemarkVerifyVariant == 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2893
    // In this second variant of verification, we flag an error
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2894
    // (i.e. an object reachable in the new marks-vector not reachable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2895
    // in the CMS marks-vector) immediately, also indicating the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2896
    // identify of an object (A) that references the unmarked object (B) --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2897
    // presumably, a mutation to A failed to be picked up by preclean/remark?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2898
    verify_after_remark_work_2();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2899
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2900
    warning("Unrecognized value %d for CMSRemarkVerifyVariant",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2901
            CMSRemarkVerifyVariant);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2902
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2903
  gclog_or_tty->print(" done] ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2904
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2905
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2906
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2907
void CMSCollector::verify_after_remark_work_1() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2908
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2909
  HandleMark  hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2910
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2911
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2912
  // 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
  2913
  MarkRefsIntoClosure notOlder(_span, verification_mark_bm());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2914
  gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2915
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2916
  gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2917
                                true,   // younger gens are roots
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2918
                                true,   // activate StrongRootsScope
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2919
                                true,   // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2920
                                SharedHeap::ScanningOption(roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2921
                                &notOlder,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2922
                                true,   // walk code active on stacks
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2923
                                NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2924
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2925
  // Now mark from the roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2926
  assert(_revisitStack.isEmpty(), "Should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2927
  MarkFromRootsClosure markFromRootsClosure(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2928
    verification_mark_bm(), verification_mark_stack(), &_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2929
    false /* don't yield */, true /* verifying */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2930
  assert(_restart_addr == NULL, "Expected pre-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2931
  verification_mark_bm()->iterate(&markFromRootsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2932
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2933
    // Deal with stack overflow: by restarting at the indicated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2934
    // address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2935
    HeapWord* ra = _restart_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2936
    markFromRootsClosure.reset(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2937
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2938
    verification_mark_bm()->iterate(&markFromRootsClosure, ra, _span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2939
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2940
  assert(verification_mark_stack()->isEmpty(), "Should have been drained");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2941
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2942
  // Should reset the revisit stack above, since no class tree
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2943
  // surgery is forthcoming.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2944
  _revisitStack.reset(); // throwing away all contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2945
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2946
  // Marking completed -- now verify that each bit marked in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2947
  // verification_mark_bm() is also marked in markBitMap(); flag all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2948
  // errors by printing corresponding objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2949
  VerifyMarkedClosure vcl(markBitMap());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2950
  verification_mark_bm()->iterate(&vcl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2951
  if (vcl.failed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2952
    gclog_or_tty->print("Verification failed");
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2953
    Universe::heap()->print_on(gclog_or_tty);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2954
    fatal("CMS: failed marking verification after remark");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2955
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2956
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2957
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2958
void CMSCollector::verify_after_remark_work_2() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2959
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2960
  HandleMark  hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2961
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2962
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2963
  // Mark from roots one level into CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2964
  MarkRefsIntoVerifyClosure notOlder(_span, verification_mark_bm(),
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  2965
                                     markBitMap());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2966
  gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2967
  gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2968
                                true,   // younger gens are roots
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2969
                                true,   // activate StrongRootsScope
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2970
                                true,   // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2971
                                SharedHeap::ScanningOption(roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2972
                                &notOlder,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2973
                                true,   // walk code active on stacks
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2974
                                NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2975
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2976
  // Now mark from the roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2977
  assert(_revisitStack.isEmpty(), "Should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2978
  MarkFromRootsVerifyClosure markFromRootsClosure(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2979
    verification_mark_bm(), markBitMap(), verification_mark_stack());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2980
  assert(_restart_addr == NULL, "Expected pre-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2981
  verification_mark_bm()->iterate(&markFromRootsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2982
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2983
    // Deal with stack overflow: by restarting at the indicated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2984
    // address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2985
    HeapWord* ra = _restart_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2986
    markFromRootsClosure.reset(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2987
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2988
    verification_mark_bm()->iterate(&markFromRootsClosure, ra, _span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2989
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2990
  assert(verification_mark_stack()->isEmpty(), "Should have been drained");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2991
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2992
  // Should reset the revisit stack above, since no class tree
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2993
  // surgery is forthcoming.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2994
  _revisitStack.reset(); // throwing away all contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2995
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2996
  // Marking completed -- now verify that each bit marked in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2997
  // verification_mark_bm() is also marked in markBitMap(); flag all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2998
  // errors by printing corresponding objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2999
  VerifyMarkedClosure vcl(markBitMap());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3000
  verification_mark_bm()->iterate(&vcl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3001
  assert(!vcl.failed(), "Else verification above should not have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3002
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3003
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3004
void ConcurrentMarkSweepGeneration::save_marks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3005
  // delegate to CMS space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3006
  cmsSpace()->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3007
  for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3008
    _par_gc_thread_states[i]->promo.startTrackingPromotions();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3009
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3010
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3011
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3012
bool ConcurrentMarkSweepGeneration::no_allocs_since_save_marks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3013
  return cmsSpace()->no_allocs_since_save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3014
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3015
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3016
#define CMS_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix)    \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3017
                                                                \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3018
void ConcurrentMarkSweepGeneration::                            \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3019
oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) {   \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3020
  cl->set_generation(this);                                     \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3021
  cmsSpace()->oop_since_save_marks_iterate##nv_suffix(cl);      \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3022
  cl->reset_generation();                                       \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3023
  save_marks();                                                 \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3024
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3025
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3026
ALL_SINCE_SAVE_MARKS_CLOSURES(CMS_SINCE_SAVE_MARKS_DEFN)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3027
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3028
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3029
ConcurrentMarkSweepGeneration::object_iterate_since_last_GC(ObjectClosure* blk)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3030
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3031
  // Not currently implemented; need to do the following. -- ysr.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3032
  // dld -- I think that is used for some sort of allocation profiler.  So it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3033
  // really means the objects allocated by the mutator since the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3034
  // GC.  We could potentially implement this cheaply by recording only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3035
  // the direct allocations in a side data structure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3036
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3037
  // I think we probably ought not to be required to support these
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3038
  // iterations at any arbitrary point; I think there ought to be some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3039
  // call to enable/disable allocation profiling in a generation/space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3040
  // and the iterator ought to return the objects allocated in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3041
  // gen/space since the enable call, or the last iterator call (which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3042
  // will probably be at a GC.)  That way, for gens like CM&S that would
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3043
  // require some extra data structure to support this, we only pay the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3044
  // cost when it's in use...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3045
  cmsSpace()->object_iterate_since_last_GC(blk);
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::younger_refs_iterate(OopsInGenClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3050
  cl->set_generation(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3051
  younger_refs_in_space_iterate(_cmsSpace, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3052
  cl->reset_generation();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3053
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3054
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3055
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3056
ConcurrentMarkSweepGeneration::oop_iterate(MemRegion mr, OopClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3057
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3058
    Generation::oop_iterate(mr, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3059
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3060
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3061
    Generation::oop_iterate(mr, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3062
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3063
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3064
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3065
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3066
ConcurrentMarkSweepGeneration::oop_iterate(OopClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3067
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3068
    Generation::oop_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3069
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3070
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3071
    Generation::oop_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3072
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3073
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3074
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3075
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3076
ConcurrentMarkSweepGeneration::object_iterate(ObjectClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3077
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3078
    Generation::object_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3079
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3080
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3081
    Generation::object_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3082
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3083
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3084
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3085
void
1893
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3086
ConcurrentMarkSweepGeneration::safe_object_iterate(ObjectClosure* cl) {
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3087
  if (freelistLock()->owned_by_self()) {
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3088
    Generation::safe_object_iterate(cl);
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3089
  } else {
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3090
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3091
    Generation::safe_object_iterate(cl);
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3092
  }
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3093
}
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3094
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3095
void
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3096
ConcurrentMarkSweepGeneration::pre_adjust_pointers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3097
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3098
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3099
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3100
ConcurrentMarkSweepGeneration::post_compact() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3101
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3102
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3103
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3104
ConcurrentMarkSweepGeneration::prepare_for_verify() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3105
  // Fix the linear allocation blocks to look like free blocks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3106
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3107
  // Locks are normally acquired/released in gc_prologue/gc_epilogue, but those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3108
  // are not called when the heap is verified during universe initialization and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3109
  // at vm shutdown.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3110
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3111
    cmsSpace()->prepare_for_verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3112
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3113
    MutexLockerEx fll(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3114
    cmsSpace()->prepare_for_verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3115
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3116
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3117
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3118
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3119
ConcurrentMarkSweepGeneration::verify(bool allow_dirty /* ignored */) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3120
  // Locks are normally acquired/released in gc_prologue/gc_epilogue, but those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3121
  // are not called when the heap is verified during universe initialization and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3122
  // at vm shutdown.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3123
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3124
    cmsSpace()->verify(false /* ignored */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3125
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3126
    MutexLockerEx fll(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3127
    cmsSpace()->verify(false /* ignored */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3128
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3129
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3130
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3131
void CMSCollector::verify(bool allow_dirty /* ignored */) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3132
  _cmsGen->verify(allow_dirty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3133
  _permGen->verify(allow_dirty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3134
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3135
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3136
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3137
bool CMSCollector::overflow_list_is_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3138
  assert(_num_par_pushes >= 0, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3139
  if (_overflow_list == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3140
    assert(_num_par_pushes == 0, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3141
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3142
  return _overflow_list == NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3143
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3144
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3145
// The methods verify_work_stacks_empty() and verify_overflow_empty()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3146
// merely consolidate assertion checks that appear to occur together frequently.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3147
void CMSCollector::verify_work_stacks_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3148
  assert(_markStack.isEmpty(), "Marking stack should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3149
  assert(overflow_list_is_empty(), "Overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3150
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3151
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3152
void CMSCollector::verify_overflow_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3153
  assert(overflow_list_is_empty(), "Overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3154
  assert(no_preserved_marks(), "No preserved marks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3155
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3156
#endif // PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3157
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3158
// 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
  3159
// 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
  3160
// unload classes if it's the case that:
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3161
// (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
  3162
//     ExplicitGCInvokesConcurrentAndUnloadsClasses is set, OR
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3163
// (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
  3164
//     (b) (i)   perm gen threshold has been crossed, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3165
//         (ii)  old gen is getting really full, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3166
//         (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
  3167
//               perm gen
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3168
// 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
  3169
// 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
  3170
// 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
  3171
// 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
  3172
// 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
  3173
// the property that concurrent_cycles_since_last_unload()
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3174
// 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
  3175
// _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
  3176
// themselves also monotonic in that sense. See check_monotonicity()
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3177
// below.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3178
bool CMSCollector::update_should_unload_classes() {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3179
  _should_unload_classes = false;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3180
  // Condition 1 above
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3181
  if (_full_gc_requested && ExplicitGCInvokesConcurrentAndUnloadsClasses) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3182
    _should_unload_classes = true;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3183
  } else if (CMSClassUnloadingEnabled) { // Condition 2.a above
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3184
    // Disjuncts 2.b.(i,ii,iii) above
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3185
    _should_unload_classes = (concurrent_cycles_since_last_unload() >=
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3186
                              CMSClassUnloadingMaxInterval)
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3187
                           || _permGen->should_concurrent_collect()
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3188
                           || _cmsGen->is_too_full();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3189
  }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3190
  return _should_unload_classes;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3191
}
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3192
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3193
bool ConcurrentMarkSweepGeneration::is_too_full() const {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3194
  bool res = should_concurrent_collect();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3195
  res = res && (occupancy() > (double)CMSIsTooFullPercentage/100.0);
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3196
  return res;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3197
}
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3198
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3199
void CMSCollector::setup_cms_unloading_and_verification_state() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3200
  const  bool should_verify =    VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3201
                             || VerifyBeforeExit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3202
  const  int  rso           =    SharedHeap::SO_Symbols | SharedHeap::SO_Strings
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3203
                             |   SharedHeap::SO_CodeCache;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3204
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3205
  if (should_unload_classes()) {   // Should unload classes this cycle
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3206
    remove_root_scanning_option(rso);  // Shrink the root set appropriately
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3207
    set_verifying(should_verify);    // Set verification state for this cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3208
    return;                            // Nothing else needs to be done at this time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3209
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3210
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3211
  // Not unloading classes this cycle
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3212
  assert(!should_unload_classes(), "Inconsitency!");
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3213
  if ((!verifying() || unloaded_classes_last_cycle()) && should_verify) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3214
    // We were not verifying, or we _were_ unloading classes in the last cycle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3215
    // AND some verification options are enabled this cycle; in this case,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3216
    // we must make sure that the deadness map is allocated if not already so,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3217
    // and cleared (if already allocated previously --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3218
    // CMSBitMap::sizeInBits() is used to determine if it's allocated).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3219
    if (perm_gen_verify_bit_map()->sizeInBits() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3220
      if (!perm_gen_verify_bit_map()->allocate(_permGen->reserved())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3221
        warning("Failed to allocate permanent generation verification CMS Bit Map;\n"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3222
                "permanent generation verification disabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3223
        return;  // Note that we leave verification disabled, so we'll retry this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3224
                 // allocation next cycle. We _could_ remember this failure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3225
                 // and skip further attempts and permanently disable verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3226
                 // attempts if that is considered more desirable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3227
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3228
      assert(perm_gen_verify_bit_map()->covers(_permGen->reserved()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3229
              "_perm_gen_ver_bit_map inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3230
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3231
      perm_gen_verify_bit_map()->clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3232
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3233
    // Include symbols, strings and code cache elements to prevent their resurrection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3234
    add_root_scanning_option(rso);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3235
    set_verifying(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3236
  } else if (verifying() && !should_verify) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3237
    // We were verifying, but some verification flags got disabled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3238
    set_verifying(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3239
    // Exclude symbols, strings and code cache elements from root scanning to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3240
    // reduce IM and RM pauses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3241
    remove_root_scanning_option(rso);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3242
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3243
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3245
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3246
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3247
HeapWord* CMSCollector::block_start(const void* p) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3248
  const HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3249
  if (_span.contains(p)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3250
    if (_cmsGen->cmsSpace()->is_in_reserved(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3251
      return _cmsGen->cmsSpace()->block_start(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3252
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3253
      assert(_permGen->cmsSpace()->is_in_reserved(addr),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3254
             "Inconsistent _span?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3255
      return _permGen->cmsSpace()->block_start(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3256
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3257
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3258
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3259
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3260
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3261
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3262
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3263
ConcurrentMarkSweepGeneration::expand_and_allocate(size_t word_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3264
                                                   bool   tlab,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3265
                                                   bool   parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3266
  assert(!tlab, "Can't deal with TLAB allocation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3267
  MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3268
  expand(word_size*HeapWordSize, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3269
    CMSExpansionCause::_satisfy_allocation);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3270
  if (GCExpandToAllocateDelayMillis > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3271
    os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3272
  }
182
eae79d9b9d46 6642634: Test nsk/regression/b6186200 crashed with SIGSEGV
ysr
parents: 180
diff changeset
  3273
  return have_lock_and_allocate(word_size, tlab);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3274
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3275
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3276
// YSR: All of this generation expansion/shrinking stuff is an exact copy of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3277
// OneContigSpaceCardGeneration, which makes me wonder if we should move this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3278
// to CardGeneration and share it...
979
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3279
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
  3280
  return CardGeneration::expand(bytes, expand_bytes);
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3281
}
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3282
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3283
void ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3284
  CMSExpansionCause::Cause cause)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3285
{
979
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3286
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3287
  bool success = expand(bytes, expand_bytes);
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3288
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3289
  // remember why we expanded; this information is used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3290
  // by shouldConcurrentCollect() when making decisions on whether to start
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3291
  // a new CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3292
  if (success) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3293
    set_expansion_cause(cause);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3294
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3295
      gclog_or_tty->print_cr("Expanded CMS gen for %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3296
        CMSExpansionCause::to_string(cause));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3297
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3298
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3299
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3300
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3301
HeapWord* ConcurrentMarkSweepGeneration::expand_and_par_lab_allocate(CMSParGCThreadState* ps, size_t word_sz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3302
  HeapWord* res = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3303
  MutexLocker x(ParGCRareEvent_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3304
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3305
    // Expansion by some other thread might make alloc OK now:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3306
    res = ps->lab.alloc(word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3307
    if (res != NULL) return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3308
    // If there's not enough expansion space available, give up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3309
    if (_virtual_space.uncommitted_size() < (word_sz * HeapWordSize)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3310
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3311
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3312
    // Otherwise, we try expansion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3313
    expand(word_sz*HeapWordSize, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3314
      CMSExpansionCause::_allocate_par_lab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3315
    // Now go around the loop and try alloc again;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3316
    // A competing par_promote might beat us to the expansion space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3317
    // so we may go around the loop again if promotion fails agaion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3318
    if (GCExpandToAllocateDelayMillis > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3319
      os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3320
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3321
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3322
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3323
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3324
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3325
bool ConcurrentMarkSweepGeneration::expand_and_ensure_spooling_space(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3326
  PromotionInfo* promo) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3327
  MutexLocker x(ParGCRareEvent_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3328
  size_t refill_size_bytes = promo->refillSize() * HeapWordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3329
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3330
    // Expansion by some other thread might make alloc OK now:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3331
    if (promo->ensure_spooling_space()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3332
      assert(promo->has_spooling_space(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3333
             "Post-condition of successful ensure_spooling_space()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3334
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3335
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3336
    // If there's not enough expansion space available, give up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3337
    if (_virtual_space.uncommitted_size() < refill_size_bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3338
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3339
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3340
    // Otherwise, we try expansion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3341
    expand(refill_size_bytes, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3342
      CMSExpansionCause::_allocate_par_spooling_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3343
    // Now go around the loop and try alloc again;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3344
    // A competing allocation might beat us to the expansion space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3345
    // so we may go around the loop again if allocation fails again.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3346
    if (GCExpandToAllocateDelayMillis > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3347
      os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3348
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3349
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3350
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3351
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3352
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3353
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3354
void ConcurrentMarkSweepGeneration::shrink(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3355
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3356
  size_t size = ReservedSpace::page_align_size_down(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3357
  if (size > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3358
    shrink_by(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3359
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3360
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3361
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3362
bool ConcurrentMarkSweepGeneration::grow_by(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3363
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3364
  bool result = _virtual_space.expand_by(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3365
  if (result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3366
    HeapWord* old_end = _cmsSpace->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3367
    size_t new_word_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3368
      heap_word_size(_virtual_space.committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3369
    MemRegion mr(_cmsSpace->bottom(), new_word_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3370
    _bts->resize(new_word_size);  // resize the block offset shared array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3371
    Universe::heap()->barrier_set()->resize_covered_region(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3372
    // Hmmmm... why doesn't CFLS::set_end verify locking?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3373
    // This is quite ugly; FIX ME XXX
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  3374
    _cmsSpace->assert_locked(freelistLock());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3375
    _cmsSpace->set_end((HeapWord*)_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3376
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3377
    // update the space and generation capacity counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3378
    if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3379
      _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3380
      _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3381
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3382
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3383
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3384
      size_t new_mem_size = _virtual_space.committed_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3385
      size_t old_mem_size = new_mem_size - bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3386
      gclog_or_tty->print_cr("Expanding %s from %ldK by %ldK to %ldK",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3387
                    name(), old_mem_size/K, bytes/K, new_mem_size/K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3388
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3389
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3390
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3391
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3392
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3393
bool ConcurrentMarkSweepGeneration::grow_to_reserved() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3394
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3395
  bool success = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3396
  const size_t remaining_bytes = _virtual_space.uncommitted_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3397
  if (remaining_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3398
    success = grow_by(remaining_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3399
    DEBUG_ONLY(if (!success) warning("grow to reserved failed");)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3400
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3401
  return success;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3402
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3403
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3404
void ConcurrentMarkSweepGeneration::shrink_by(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3405
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3406
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3407
  // XXX Fix when compaction is implemented.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3408
  warning("Shrinking of CMS not yet implemented");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3409
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3410
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3411
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3412
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3413
// Simple ctor/dtor wrapper for accounting & timer chores around concurrent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3414
// phases.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3415
class CMSPhaseAccounting: public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3416
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3417
  CMSPhaseAccounting(CMSCollector *collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3418
                     const char *phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3419
                     bool print_cr = true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3420
  ~CMSPhaseAccounting();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3421
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3422
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3423
  CMSCollector *_collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3424
  const char *_phase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3425
  elapsedTimer _wallclock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3426
  bool _print_cr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3427
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3428
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3429
  // Not MT-safe; so do not pass around these StackObj's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3430
  // where they may be accessed by other threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3431
  jlong wallclock_millis() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3432
    assert(_wallclock.is_active(), "Wall clock should not stop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3433
    _wallclock.stop();  // to record time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3434
    jlong ret = _wallclock.milliseconds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3435
    _wallclock.start(); // restart
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3436
    return ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3437
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3438
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3439
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3440
CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3441
                                       const char *phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3442
                                       bool print_cr) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3443
  _collector(collector), _phase(phase), _print_cr(print_cr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3444
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3445
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3446
    _collector->resetYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3447
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3448
  if (PrintGCDetails && PrintGCTimeStamps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3449
    gclog_or_tty->date_stamp(PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3450
    gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3451
    gclog_or_tty->print_cr(": [%s-concurrent-%s-start]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3452
      _collector->cmsGen()->short_name(), _phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3453
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3454
  _collector->resetTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3455
  _wallclock.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3456
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3457
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3458
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3459
CMSPhaseAccounting::~CMSPhaseAccounting() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3460
  assert(_wallclock.is_active(), "Wall clock should not have stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3461
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3462
  _wallclock.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3463
  if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3464
    gclog_or_tty->date_stamp(PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3465
    if (PrintGCTimeStamps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3466
      gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3467
      gclog_or_tty->print(": ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3468
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3469
    gclog_or_tty->print("[%s-concurrent-%s: %3.3f/%3.3f secs]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3470
                 _collector->cmsGen()->short_name(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3471
                 _phase, _collector->timerValue(), _wallclock.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3472
    if (_print_cr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3473
      gclog_or_tty->print_cr("");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3474
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3475
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3476
      gclog_or_tty->print_cr(" (CMS-concurrent-%s yielded %d times)", _phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3477
                    _collector->yields());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3478
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3479
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3480
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3481
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3482
// CMS work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3483
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3484
// Checkpoint the roots into this generation from outside
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3485
// this generation. [Note this initial checkpoint need only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3486
// be approximate -- we'll do a catch up phase subsequently.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3487
void CMSCollector::checkpointRootsInitial(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3488
  assert(_collectorState == InitialMarking, "Wrong collector state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3489
  check_correct_thread_executing();
6245
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  3490
  TraceCMSMemoryManagerStats tms(_collectorState);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3491
  ReferenceProcessor* rp = ref_processor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3492
  SpecializationStats::clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3493
  assert(_restart_addr == NULL, "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3494
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3495
    // acquire locks for subsequent manipulations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3496
    MutexLockerEx x(bitMapLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3497
                    Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3498
    checkpointRootsInitialWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3499
    rp->verify_no_references_recorded();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3500
    rp->enable_discovery(); // enable ("weak") refs discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3501
    _collectorState = Marking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3502
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3503
    // (Weak) Refs discovery: this is controlled from genCollectedHeap::do_collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3504
    // which recognizes if we are a CMS generation, and doesn't try to turn on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3505
    // discovery; verify that they aren't meddling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3506
    assert(!rp->discovery_is_atomic(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3507
           "incorrect setting of discovery predicate");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3508
    assert(!rp->discovery_enabled(), "genCollectedHeap shouldn't control "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3509
           "ref discovery for this generation kind");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3510
    // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3511
    checkpointRootsInitialWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3512
    rp->enable_discovery(); // now enable ("weak") refs discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3513
    _collectorState = Marking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3514
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3515
  SpecializationStats::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3516
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3517
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3518
void CMSCollector::checkpointRootsInitialWork(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3519
  assert(SafepointSynchronize::is_at_safepoint(), "world should be stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3520
  assert(_collectorState == InitialMarking, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3521
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3522
  // If there has not been a GC[n-1] since last GC[n] cycle completed,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3523
  // precede our marking with a collection of all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3524
  // younger generations to keep floating garbage to a minimum.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3525
  // XXX: we won't do this for now -- it's an optimization to be done later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3526
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3527
  // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3528
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3529
  assert(_markBitMap.isAllClear(), "was reset at end of previous cycle");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3530
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3531
  // Setup the verification and class unloading state for this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3532
  // CMS collection cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3533
  setup_cms_unloading_and_verification_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3534
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3535
  NOT_PRODUCT(TraceTime t("\ncheckpointRootsInitialWork",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3536
    PrintGCDetails && Verbose, true, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3537
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3538
    size_policy()->checkpoint_roots_initial_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3539
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3540
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3541
  // Reset all the PLAB chunk arrays if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3542
  if (_survivor_plab_array != NULL && !CMSPLABRecordAlways) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3543
    reset_survivor_plab_arrays();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3544
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3545
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3546
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3547
  HandleMark  hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3548
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3549
  FalseClosure falseClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3550
  // In the case of a synchronous collection, we will elide the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3551
  // 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
  3552
  // in this step.
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  3553
  // 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
  3554
  // 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
  3555
  MarkRefsIntoClosure notOlder(_span, &_markBitMap);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3556
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3557
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3558
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3559
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3560
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3561
  gch->ensure_parsability(false);  // fill TLABs, but no need to retire them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3562
  // Update the saved marks which may affect the root scans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3563
  gch->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3564
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3565
  // weak reference processing has not started yet.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3566
  ref_processor()->set_enqueuing_is_done(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3567
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3568
  {
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  3569
    // This is not needed. DEBUG_ONLY(RememberKlassesChecker imx(true);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3570
    COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3571
    gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3572
    gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3573
                                  true,   // younger gens are roots
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  3574
                                  true,   // activate StrongRootsScope
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3575
                                  true,   // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3576
                                  SharedHeap::ScanningOption(roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  3577
                                  &notOlder,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  3578
                                  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
  3579
                                  NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3580
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3581
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3582
  // Clear mod-union table; it will be dirtied in the prologue of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3583
  // CMS generation per each younger generation collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3584
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3585
  assert(_modUnionTable.isAllClear(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3586
       "Was cleared in most recent final checkpoint phase"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3587
       " or no bits are set in the gc_prologue before the start of the next "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3588
       "subsequent marking phase.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3589
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3590
  // Temporarily disabled, since pre/post-consumption closures don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3591
  // care about precleaned cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3592
  #if 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3593
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3594
    MemRegion mr = MemRegion((HeapWord*)_virtual_space.low(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3595
                             (HeapWord*)_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3596
    _ct->ct_bs()->preclean_dirty_cards(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3597
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3598
  #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3599
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3600
  // Save the end of the used_region of the constituent generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3601
  // to be used to limit the extent of sweep in each generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3602
  save_sweep_limits();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3603
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3604
    size_policy()->checkpoint_roots_initial_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3605
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3606
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3607
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3608
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3609
bool CMSCollector::markFromRoots(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3610
  // we might be tempted to assert that:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3611
  // assert(asynch == !SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3612
  //        "inconsistent argument?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3613
  // However that wouldn't be right, because it's possible that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3614
  // a safepoint is indeed in progress as a younger generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3615
  // stop-the-world GC happens even as we mark in this generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3616
  assert(_collectorState == Marking, "inconsistent state?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3617
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3618
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3619
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3620
  bool res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3621
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3622
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3623
    // Start the timers for adaptive size policy for the concurrent phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3624
    // Do it here so that the foreground MS can use the concurrent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3625
    // timer since a foreground MS might has the sweep done concurrently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3626
    // or STW.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3627
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3628
      size_policy()->concurrent_marking_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3629
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3630
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3631
    // Weak ref discovery note: We may be discovering weak
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3632
    // refs in this generation concurrent (but interleaved) with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3633
    // weak ref discovery by a younger generation collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3634
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3635
    CMSTokenSyncWithLocks ts(true, bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3636
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3637
    CMSPhaseAccounting pa(this, "mark", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3638
    res = markFromRootsWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3639
    if (res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3640
      _collectorState = Precleaning;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3641
    } else { // We failed and a foreground collection wants to take over
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3642
      assert(_foregroundGCIsActive, "internal state inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3643
      assert(_restart_addr == NULL,  "foreground will restart from scratch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3644
      if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3645
        gclog_or_tty->print_cr("bailing out to foreground collection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3646
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3647
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3648
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3649
      size_policy()->concurrent_marking_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3650
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3651
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3652
    assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3653
           "inconsistent with asynch == false");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3654
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3655
      size_policy()->ms_collection_marking_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3656
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3657
    // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3658
    res = markFromRootsWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3659
    _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3660
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3661
      GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3662
      size_policy()->ms_collection_marking_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3663
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3664
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3665
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3666
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3667
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3668
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3669
bool CMSCollector::markFromRootsWork(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3670
  // iterate over marked bits in bit map, doing a full scan and mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3671
  // from these roots using the following algorithm:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3672
  // . if oop is to the right of the current scan pointer,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3673
  //   mark corresponding bit (we'll process it later)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3674
  // . else (oop is to left of current scan pointer)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3675
  //   push oop on marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3676
  // . drain the marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3677
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3678
  // Note that when we do a marking step we need to hold the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3679
  // bit map lock -- recall that direct allocation (by mutators)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3680
  // and promotion (by younger generation collectors) is also
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3681
  // marking the bit map. [the so-called allocate live policy.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3682
  // Because the implementation of bit map marking is not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3683
  // robust wrt simultaneous marking of bits in the same word,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3684
  // we need to make sure that there is no such interference
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3685
  // between concurrent such updates.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3686
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3687
  // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3688
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3689
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3690
  // Clear the revisit stack, just in case there are any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3691
  // obsolete contents from a short-circuited previous CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3692
  _revisitStack.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3693
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3694
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3695
  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
  3696
  DEBUG_ONLY(RememberKlassesChecker cmx(should_unload_classes());)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3697
  bool result = false;
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
  3698
  if (CMSConcurrentMTEnabled && ConcGCThreads > 0) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3699
    result = do_marking_mt(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3700
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3701
    result = do_marking_st(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3702
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3703
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3704
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3705
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3706
// Forward decl
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3707
class CMSConcMarkingTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3708
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3709
class CMSConcMarkingTerminator: public ParallelTaskTerminator {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3710
  CMSCollector*       _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3711
  CMSConcMarkingTask* _task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3712
  bool _yield;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3713
 protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3714
  virtual void yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3715
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3716
  // "n_threads" is the number of threads to be terminated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3717
  // "queue_set" is a set of work queues of other threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3718
  // "collector" is the CMS collector associated with this task terminator.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3719
  // "yield" indicates whether we need the gang as a whole to yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3720
  CMSConcMarkingTerminator(int n_threads, TaskQueueSetSuper* queue_set,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3721
                           CMSCollector* collector, bool yield) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3722
    ParallelTaskTerminator(n_threads, queue_set),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3723
    _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3724
    _yield(yield) { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3725
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3726
  void set_task(CMSConcMarkingTask* task) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3727
    _task = task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3728
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3729
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3730
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3731
// MT Concurrent Marking Task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3732
class CMSConcMarkingTask: public YieldingFlexibleGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3733
  CMSCollector* _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3734
  YieldingFlexibleWorkGang* _workers;        // the whole gang
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;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3740
  HeapWord*     _global_finger;
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3741
  HeapWord*     _restart_addr;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3742
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3743
  //  Exposed here for yielding support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3744
  Mutex* const _bit_map_lock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3745
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3746
  // The per thread work queues, available here for stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3747
  OopTaskQueueSet*  _task_queues;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3748
  CMSConcMarkingTerminator _term;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3749
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3750
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3751
  CMSConcMarkingTask(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3752
                 CompactibleFreeListSpace* cms_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3753
                 CompactibleFreeListSpace* perm_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3754
                 bool asynch, int n_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3755
                 YieldingFlexibleWorkGang* workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3756
                 OopTaskQueueSet* task_queues):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3757
    YieldingFlexibleGangTask("Concurrent marking done multi-threaded"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3758
    _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3759
    _cms_space(cms_space),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3760
    _perm_space(perm_space),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3761
    _asynch(asynch), _n_workers(n_workers), _result(true),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3762
    _workers(workers), _task_queues(task_queues),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3763
    _term(n_workers, task_queues, _collector, asynch),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3764
    _bit_map_lock(collector->bitMapLock())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3765
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3766
    assert(n_workers <= workers->total_workers(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3767
           "Else termination won't work correctly today"); // XXX FIX ME!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3768
    _requested_size = n_workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3769
    _term.set_task(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3770
    assert(_cms_space->bottom() < _perm_space->bottom(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3771
           "Finger incorrectly initialized below");
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3772
    _restart_addr = _global_finger = _cms_space->bottom();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3773
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3774
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3775
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3776
  OopTaskQueueSet* task_queues()  { return _task_queues; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3777
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3778
  OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3779
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3780
  HeapWord** global_finger_addr() { return &_global_finger; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3781
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3782
  CMSConcMarkingTerminator* terminator() { return &_term; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3784
  void work(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3785
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3786
  virtual void coordinator_yield();  // stuff done by coordinator
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3787
  bool result() { return _result; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3788
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3789
  void reset(HeapWord* ra) {
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3790
    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
  3791
    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
  3792
    assert(ra             <  _perm_space->end(), "ra too large");
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3793
    _restart_addr = _global_finger = ra;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3794
    _term.reset_for_reuse();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3795
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3796
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3797
  static bool get_work_from_overflow_stack(CMSMarkStack* ovflw_stk,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3798
                                           OopTaskQueue* work_q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3799
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3800
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3801
  void do_scan_and_mark(int i, CompactibleFreeListSpace* sp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3802
  void do_work_steal(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3803
  void bump_global_finger(HeapWord* f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3804
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3805
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3806
void CMSConcMarkingTerminator::yield() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3807
  if (ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3808
      !_collector->foregroundGCIsActive() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3809
      _yield) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3810
    _task->yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3811
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3812
    ParallelTaskTerminator::yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3813
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3814
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3815
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3816
////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3817
// Concurrent Marking Algorithm Sketch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3818
////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3819
// Until all tasks exhausted (both spaces):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3820
// -- claim next available chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3821
// -- bump global finger via CAS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3822
// -- find first object that starts in this chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3823
//    and start scanning bitmap from that position
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3824
// -- scan marked objects for oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3825
// -- CAS-mark target, and if successful:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3826
//    . if target oop is above global finger (volatile read)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3827
//      nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3828
//    . if target oop is in chunk and above local finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3829
//        then nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3830
//    . else push on work-queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3831
// -- Deal with possible overflow issues:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3832
//    . local work-queue overflow causes stuff to be pushed on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3833
//      global (common) overflow queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3834
//    . always first empty local work queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3835
//    . then get a batch of oops from global work queue if any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3836
//    . then do work stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3837
// -- When all tasks claimed (both spaces)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3838
//    and local work queue empty,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3839
//    then in a loop do:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3840
//    . check global overflow stack; steal a batch of oops and trace
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3841
//    . try to steal from other threads oif GOS is empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3842
//    . if neither is available, offer termination
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3843
// -- Terminate and return result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3844
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3845
void CMSConcMarkingTask::work(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3846
  elapsedTimer _timer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3847
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3848
  HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3849
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3850
  DEBUG_ONLY(_collector->verify_overflow_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3851
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3852
  // Before we begin work, our work queue should be empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3853
  assert(work_queue(i)->size() == 0, "Expected to be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3854
  // Scan the bitmap covering _cms_space, tracing through grey objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3855
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3856
  do_scan_and_mark(i, _cms_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3857
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3858
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3859
    gclog_or_tty->print_cr("Finished cms space scanning in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3860
      i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3861
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3862
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3863
  // ... do the same for the _perm_space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3864
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3865
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3866
  do_scan_and_mark(i, _perm_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3867
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3868
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3869
    gclog_or_tty->print_cr("Finished perm space scanning in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3870
      i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3871
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3872
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3873
  // ... do work stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3874
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3875
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3876
  do_work_steal(i);
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 work stealing 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
  assert(_collector->_markStack.isEmpty(), "Should have been emptied");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3883
  assert(work_queue(i)->size() == 0, "Should have been emptied");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3884
  // Note that under the current task protocol, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3885
  // following assertion is true even of the spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3886
  // expanded since the completion of the concurrent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3887
  // marking. XXX This will likely change under a strict
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3888
  // ABORT semantics.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3889
  assert(_global_finger >  _cms_space->end() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3890
         _global_finger >= _perm_space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3891
         "All tasks have been completed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3892
  DEBUG_ONLY(_collector->verify_overflow_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3893
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3894
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3895
void CMSConcMarkingTask::bump_global_finger(HeapWord* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3896
  HeapWord* read = _global_finger;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3897
  HeapWord* cur  = read;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3898
  while (f > read) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3899
    cur = read;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3900
    read = (HeapWord*) Atomic::cmpxchg_ptr(f, &_global_finger, cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3901
    if (cur == read) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3902
      // our cas succeeded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3903
      assert(_global_finger >= f, "protocol consistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3904
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3905
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3906
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3907
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3908
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3909
// This is really inefficient, and should be redone by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3910
// using (not yet available) block-read and -write interfaces to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3911
// stack and the work_queue. XXX FIX ME !!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3912
bool CMSConcMarkingTask::get_work_from_overflow_stack(CMSMarkStack* ovflw_stk,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3913
                                                      OopTaskQueue* work_q) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3914
  // Fast lock-free check
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3915
  if (ovflw_stk->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3916
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3917
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3918
  assert(work_q->size() == 0, "Shouldn't steal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3919
  MutexLockerEx ml(ovflw_stk->par_lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3920
                   Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3921
  // 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
  3922
  size_t num = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3923
                    (size_t)ParGCDesiredObjsFromOverflowList);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3924
  num = MIN2(num, ovflw_stk->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3925
  for (int i = (int) num; i > 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3926
    oop cur = ovflw_stk->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3927
    assert(cur != NULL, "Counted wrong?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3928
    work_q->push(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3929
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3930
  return num > 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3931
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3932
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3933
void CMSConcMarkingTask::do_scan_and_mark(int i, CompactibleFreeListSpace* sp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3934
  SequentialSubTasksDone* pst = sp->conc_par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3935
  int n_tasks = pst->n_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3936
  // We allow that there may be no tasks to do here because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3937
  // we are restarting after a stack overflow.
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3938
  assert(pst->valid() || n_tasks == 0, "Uninitialized use?");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3939
  int nth_task = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3940
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3941
  HeapWord* aligned_start = sp->bottom();
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3942
  if (sp->used_region().contains(_restart_addr)) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3943
    // 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
  3944
    // for this space.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3945
    aligned_start =
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3946
      (HeapWord*)align_size_down((uintptr_t)_restart_addr,
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3947
                                 CardTableModRefBS::card_size);
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3948
  }
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3949
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3950
  size_t chunk_size = sp->marking_task_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3951
  while (!pst->is_task_claimed(/* reference */ nth_task)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3952
    // Having claimed the nth task in this space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3953
    // compute the chunk that it corresponds to:
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3954
    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
  3955
                               aligned_start + (nth_task+1)*chunk_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3956
    // Try and bump the global finger via a CAS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3957
    // note that we need to do the global finger bump
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3958
    // _before_ taking the intersection below, because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3959
    // the task corresponding to that region will be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3960
    // deemed done even if the used_region() expands
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3961
    // because of allocation -- as it almost certainly will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3962
    // during start-up while the threads yield in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3963
    // closure below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3964
    HeapWord* finger = span.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3965
    bump_global_finger(finger);   // atomically
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3966
    // There are null tasks here corresponding to chunks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3967
    // beyond the "top" address of the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3968
    span = span.intersection(sp->used_region());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3969
    if (!span.is_empty()) {  // Non-null task
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3970
      HeapWord* prev_obj;
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3971
      assert(!span.contains(_restart_addr) || nth_task == 0,
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3972
             "Inconsistency");
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3973
      if (nth_task == 0) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3974
        // 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
  3975
        if (span.contains(_restart_addr)) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3976
          // 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
  3977
          // we might additionally skip a chunk prefix.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3978
          prev_obj = _restart_addr;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3979
        } else {
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3980
          prev_obj = span.start();
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3981
        }
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3982
      } else {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3983
        // We want to skip the first object because
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3984
        // 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
  3985
        // that _starts_ in this span; a fortiori, any
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3986
        // object starting in an earlier span is scanned
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3987
        // as part of an earlier claimed task.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3988
        // 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
  3989
        // 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
  3990
        prev_obj = sp->block_start_careful(span.start());
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3991
        // 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
  3992
        // Printezis bits to avoid waiting for allocated
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3993
        // objects to become initialized/parsable.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3994
        while (prev_obj < span.start()) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3995
          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
  3996
          if (sz > 0) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3997
            prev_obj += sz;
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3998
          } else {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3999
            // 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
  4000
            // scanning, but that appears unavoidable, short of
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4001
            // locking the free list locks; see bug 6324141.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4002
            break;
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4003
          }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4004
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4005
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4006
      if (prev_obj < span.end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4007
        MemRegion my_span = MemRegion(prev_obj, span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4008
        // Do the marking work within a non-empty span --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4009
        // the last argument to the constructor indicates whether the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4010
        // iteration should be incremental with periodic yields.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4011
        Par_MarkFromRootsClosure cl(this, _collector, my_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4012
                                    &_collector->_markBitMap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4013
                                    work_queue(i),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4014
                                    &_collector->_markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4015
                                    &_collector->_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4016
                                    _asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4017
        _collector->_markBitMap.iterate(&cl, my_span.start(), my_span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4018
      } // else nothing to do for this task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4019
    }   // else nothing to do for this task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4020
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4021
  // We'd be tempted to assert here that since there are no
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4022
  // more tasks left to claim in this space, the global_finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4023
  // must exceed space->top() and a fortiori space->end(). However,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4024
  // that would not quite be correct because the bumping of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4025
  // global_finger occurs strictly after the claiming of a task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4026
  // so by the time we reach here the global finger may not yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4027
  // have been bumped up by the thread that claimed the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4028
  // task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4029
  pst->all_tasks_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4030
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4031
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4032
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
  4033
 private:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4034
  MemRegion     _span;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4035
  CMSBitMap*    _bit_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4036
  CMSMarkStack* _overflow_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4037
  OopTaskQueue* _work_queue;
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4038
 protected:
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4039
  DO_OOP_WORK_DEFN
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4040
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4041
  Par_ConcMarkingClosure(CMSCollector* collector, OopTaskQueue* work_queue,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4042
                         CMSBitMap* bit_map, CMSMarkStack* overflow_stack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4043
                         CMSMarkStack* revisit_stack):
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4044
    Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4045
    _span(_collector->_span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4046
    _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4047
    _bit_map(bit_map),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4048
    _overflow_stack(overflow_stack)
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4049
  { }
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4050
  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
  4051
  virtual void do_oop(narrowOop* p);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4052
  void trim_queue(size_t max);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4053
  void handle_stack_overflow(HeapWord* lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4054
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4055
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4056
// Grey object scanning during work stealing phase --
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4057
// the salient assumption here is that any references
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4058
// 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
  4059
// 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
  4060
// 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
  4061
// 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
  4062
void Par_ConcMarkingClosure::do_oop(oop obj) {
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4063
  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
  4064
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4065
  // Check if oop points into the CMS generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4066
  // and is not marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4067
  if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4068
    // a white object ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4069
    // If we manage to "claim" the object, by being the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4070
    // first thread to mark it, then we push it on our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4071
    // marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4072
    if (_bit_map->par_mark(addr)) {     // ... now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4073
      // push on work queue (grey set)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4074
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4075
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4076
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4077
            _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4078
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4079
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4080
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4081
      )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4082
      if (simulate_overflow ||
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4083
          !(_work_queue->push(obj) || _overflow_stack->par_push(obj))) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4084
        // stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4085
        if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4086
          gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4087
                                 SIZE_FORMAT, _overflow_stack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4088
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4089
        // We cannot assert that the overflow stack is full because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4090
        // it may have been emptied since.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4091
        assert(simulate_overflow ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4092
               _work_queue->size() == _work_queue->max_elems(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4093
              "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4094
        handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4095
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4096
    } // Else, some other thread got there first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4097
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4098
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4099
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4100
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
  4101
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
  4102
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4103
void Par_ConcMarkingClosure::trim_queue(size_t max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4104
  while (_work_queue->size() > max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4105
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4106
    if (_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4107
      assert(new_oop->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4108
      assert(_bit_map->isMarked((HeapWord*)new_oop), "Grey object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4109
      assert(_span.contains((HeapWord*)new_oop), "Not in span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4110
      assert(new_oop->is_parsable(), "Should be parsable");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4111
      new_oop->oop_iterate(this);  // do_oop() above
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4112
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4113
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4114
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4115
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4116
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4117
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4118
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4119
void Par_ConcMarkingClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4120
  // 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
  4121
  // workers from interfering with the work done below.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4122
  MutexLockerEx ml(_overflow_stack->par_lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4123
                   Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4124
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4125
  HeapWord* ra = (HeapWord*)_overflow_stack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4126
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4127
  _overflow_stack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4128
  _overflow_stack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4129
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4130
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4131
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4132
void CMSConcMarkingTask::do_work_steal(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4133
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4134
  oop obj_to_scan;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4135
  CMSBitMap* bm = &(_collector->_markBitMap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4136
  CMSMarkStack* ovflw = &(_collector->_markStack);
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4137
  CMSMarkStack* revisit = &(_collector->_revisitStack);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4138
  int* seed = _collector->hash_seed(i);
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4139
  Par_ConcMarkingClosure cl(_collector, work_q, bm, ovflw, revisit);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4140
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4141
    cl.trim_queue(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4142
    assert(work_q->size() == 0, "Should have been emptied above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4143
    if (get_work_from_overflow_stack(ovflw, work_q)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4144
      // Can't assert below because the work obtained from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4145
      // overflow stack may already have been stolen from us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4146
      // assert(work_q->size() > 0, "Work from overflow stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4147
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4148
    } else if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4149
      assert(obj_to_scan->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4150
      assert(bm->isMarked((HeapWord*)obj_to_scan), "Grey object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4151
      obj_to_scan->oop_iterate(&cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4152
    } else if (terminator()->offer_termination()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4153
      assert(work_q->size() == 0, "Impossible!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4154
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4155
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4156
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4157
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4158
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4159
// This is run by the CMS (coordinator) thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4160
void CMSConcMarkingTask::coordinator_yield() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4161
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4162
         "CMS thread should hold CMS token");
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4163
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4164
  // First give up the locks, then yield, then re-lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4165
  // We should probably use a constructor/destructor idiom to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4166
  // do this unlock/lock or modify the MutexUnlocker class to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4167
  // serve our purpose. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4168
  assert_lock_strong(_bit_map_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4169
  _bit_map_lock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4170
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4171
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4172
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4173
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4174
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4175
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4176
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4177
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4178
  // It is possible for whichever thread initiated the yield request
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4179
  // not to get a chance to wake up and take the bitmap lock between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4180
  // this thread releasing it and reacquiring it. So, while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4181
  // should_yield() flag is on, let's sleep for a bit to give the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4182
  // other thread a chance to wake up. The limit imposed on the number
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4183
  // of iterations is defensive, to avoid any unforseen circumstances
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4184
  // putting us into an infinite loop. Since it's always been this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4185
  // (coordinator_yield()) method that was observed to cause the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4186
  // problem, we are using a parameter (CMSCoordinatorYieldSleepCount)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4187
  // which is by default non-zero. For the other seven methods that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4188
  // also perform the yield operation, as are using a different
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4189
  // parameter (CMSYieldSleepCount) which is by default zero. This way we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4190
  // can enable the sleeping for those methods too, if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4191
  // See 6442774.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4192
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4193
  // We really need to reconsider the synchronization between the GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4194
  // thread and the yield-requesting threads in the future and we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4195
  // should really use wait/notify, which is the recommended
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4196
  // way of doing this type of interaction. Additionally, we should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4197
  // consolidate the eight methods that do the yield operation and they
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4198
  // are almost identical into one for better maintenability and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4199
  // readability. See 6445193.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4200
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4201
  // Tony 2006.06.29
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4202
  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
  4203
                   ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4204
                   !CMSCollector::foregroundGCIsActive(); ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4205
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4206
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4207
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4208
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4209
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4210
  _bit_map_lock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4211
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4212
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4213
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4214
bool CMSCollector::do_marking_mt(bool asynch) {
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
  4215
  assert(ConcGCThreads > 0 && conc_workers() != NULL, "precondition");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4216
  // In the future this would be determined ergonomically, based
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4217
  // 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
  4218
  int num_workers = ConcGCThreads;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4219
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4220
  CompactibleFreeListSpace* cms_space  = _cmsGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4221
  CompactibleFreeListSpace* perm_space = _permGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4222
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4223
  CMSConcMarkingTask tsk(this, cms_space, perm_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4224
                         asynch, num_workers /* number requested XXX */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4225
                         conc_workers(), task_queues());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4226
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4227
  // Since the actual number of workers we get may be different
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4228
  // from the number we requested above, do we need to do anything different
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4229
  // below? In particular, may be we need to subclass the SequantialSubTasksDone
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4230
  // class?? XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4231
  cms_space ->initialize_sequential_subtasks_for_marking(num_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4232
  perm_space->initialize_sequential_subtasks_for_marking(num_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4233
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4234
  // Refs discovery is already non-atomic.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4235
  assert(!ref_processor()->discovery_is_atomic(), "Should be non-atomic");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4236
  // Mutate the Refs discovery so it is MT during the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4237
  // multi-threaded marking phase.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4238
  ReferenceProcessorMTMutator mt(ref_processor(), num_workers > 1);
4738
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4574
diff changeset
  4239
  DEBUG_ONLY(RememberKlassesChecker cmx(should_unload_classes());)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4240
  conc_workers()->start_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4241
  while (tsk.yielded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4242
    tsk.coordinator_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4243
    conc_workers()->continue_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4244
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4245
  // If the task was aborted, _restart_addr will be non-NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4246
  assert(tsk.completed() || _restart_addr != NULL, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4247
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4248
    // XXX For now we do not make use of ABORTED state and have not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4249
    // yet implemented the right abort semantics (even in the original
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4250
    // single-threaded CMS case). That needs some more investigation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4251
    // and is deferred for now; see CR# TBF. 07252005YSR. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4252
    assert(!CMSAbortSemantics || tsk.aborted(), "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4253
    // If _restart_addr is non-NULL, a marking stack overflow
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1910
diff changeset
  4254
    // occurred; we need to do a fresh marking iteration from the
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4255
    // indicated restart address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4256
    if (_foregroundGCIsActive && asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4257
      // We may be running into repeated stack overflows, having
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4258
      // reached the limit of the stack size, while making very
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4259
      // slow forward progress. It may be best to bail out and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4260
      // let the foreground collector do its job.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4261
      // Clear _restart_addr, so that foreground GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4262
      // works from scratch. This avoids the headache of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4263
      // a "rescan" which would otherwise be needed because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4264
      // of the dirty mod union table & card table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4265
      _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4266
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4267
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4268
    // Adjust the task to restart from _restart_addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4269
    tsk.reset(_restart_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4270
    cms_space ->initialize_sequential_subtasks_for_marking(num_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4271
                  _restart_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4272
    perm_space->initialize_sequential_subtasks_for_marking(num_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4273
                  _restart_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4274
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4275
    // Get the workers going again
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4276
    conc_workers()->start_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4277
    while (tsk.yielded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4278
      tsk.coordinator_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4279
      conc_workers()->continue_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4280
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4281
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4282
  assert(tsk.completed(), "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4283
  assert(tsk.result() == true, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4284
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4285
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4286
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4287
bool CMSCollector::do_marking_st(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4288
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4289
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4290
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4291
  MarkFromRootsClosure markFromRootsClosure(this, _span, &_markBitMap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4292
    &_markStack, &_revisitStack, CMSYield && asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4293
  // the last argument to iterate indicates whether the iteration
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4294
  // should be incremental with periodic yields.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4295
  _markBitMap.iterate(&markFromRootsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4296
  // If _restart_addr is non-NULL, a marking stack overflow
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1910
diff changeset
  4297
  // occurred; we need to do a fresh iteration from the
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4298
  // indicated restart address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4299
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4300
    if (_foregroundGCIsActive && asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4301
      // We may be running into repeated stack overflows, having
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4302
      // reached the limit of the stack size, while making very
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4303
      // slow forward progress. It may be best to bail out and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4304
      // let the foreground collector do its job.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4305
      // Clear _restart_addr, so that foreground GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4306
      // works from scratch. This avoids the headache of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4307
      // a "rescan" which would otherwise be needed because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4308
      // of the dirty mod union table & card table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4309
      _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4310
      return false;  // indicating failure to complete marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4311
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4312
    // Deal with stack overflow:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4313
    // we restart marking from _restart_addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4314
    HeapWord* ra = _restart_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4315
    markFromRootsClosure.reset(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4316
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4317
    _markBitMap.iterate(&markFromRootsClosure, ra, _span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4318
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4319
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4320
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4321
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4322
void CMSCollector::preclean() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4323
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4324
  assert(Thread::current()->is_ConcurrentGC_thread(), "Wrong thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4325
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4326
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4327
  _abort_preclean = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4328
  if (CMSPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4329
    _eden_chunk_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4330
    size_t used = get_eden_used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4331
    size_t capacity = get_eden_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4332
    // Don't start sampling unless we will get sufficiently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4333
    // many samples.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4334
    if (used < (capacity/(CMSScheduleRemarkSamplingRatio * 100)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4335
                * CMSScheduleRemarkEdenPenetration)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4336
      _start_sampling = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4337
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4338
      _start_sampling = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4339
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4340
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4341
    CMSPhaseAccounting pa(this, "preclean", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4342
    preclean_work(CMSPrecleanRefLists1, CMSPrecleanSurvivors1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4343
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4344
  CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4345
  if (CMSPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4346
    sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4347
    _collectorState = AbortablePreclean;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4348
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4349
    _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4350
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4351
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4352
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4353
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4354
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4355
// Try and schedule the remark such that young gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4356
// occupancy is CMSScheduleRemarkEdenPenetration %.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4357
void CMSCollector::abortable_preclean() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4358
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4359
  assert(CMSPrecleaningEnabled,  "Inconsistent control state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4360
  assert(_collectorState == AbortablePreclean, "Inconsistent control state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4361
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4362
  // If Eden's current occupancy is below this threshold,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4363
  // immediately schedule the remark; else preclean
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4364
  // past the next scavenge in an effort to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4365
  // schedule the pause as described avove. By choosing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4366
  // CMSScheduleRemarkEdenSizeThreshold >= max eden size
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4367
  // we will never do an actual abortable preclean cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4368
  if (get_eden_used() > CMSScheduleRemarkEdenSizeThreshold) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4369
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4370
    CMSPhaseAccounting pa(this, "abortable-preclean", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4371
    // We need more smarts in the abortable preclean
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4372
    // loop below to deal with cases where allocation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4373
    // in young gen is very very slow, and our precleaning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4374
    // is running a losing race against a horde of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4375
    // mutators intent on flooding us with CMS updates
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4376
    // (dirty cards).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4377
    // One, admittedly dumb, strategy is to give up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4378
    // after a certain number of abortable precleaning loops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4379
    // or after a certain maximum time. We want to make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4380
    // this smarter in the next iteration.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4381
    // XXX FIX ME!!! YSR
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4382
    size_t loops = 0, workdone = 0, cumworkdone = 0, waited = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4383
    while (!(should_abort_preclean() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4384
             ConcurrentMarkSweepThread::should_terminate())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4385
      workdone = preclean_work(CMSPrecleanRefLists2, CMSPrecleanSurvivors2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4386
      cumworkdone += workdone;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4387
      loops++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4388
      // Voluntarily terminate abortable preclean phase if we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4389
      // been at it for too long.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4390
      if ((CMSMaxAbortablePrecleanLoops != 0) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4391
          loops >= CMSMaxAbortablePrecleanLoops) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4392
        if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4393
          gclog_or_tty->print(" CMS: abort preclean due to loops ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4394
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4395
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4396
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4397
      if (pa.wallclock_millis() > CMSMaxAbortablePrecleanTime) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4398
        if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4399
          gclog_or_tty->print(" CMS: abort preclean due to time ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4400
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4401
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4402
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4403
      // If we are doing little work each iteration, we should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4404
      // take a short break.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4405
      if (workdone < CMSAbortablePrecleanMinWorkPerIteration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4406
        // Sleep for some time, waiting for work to accumulate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4407
        stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4408
        cmsThread()->wait_on_cms_lock(CMSAbortablePrecleanWaitMillis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4409
        startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4410
        waited++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4411
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4412
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4413
    if (PrintCMSStatistics > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4414
      gclog_or_tty->print(" [%d iterations, %d waits, %d cards)] ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4415
                          loops, waited, cumworkdone);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4416
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4417
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4418
  CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4419
  if (_collectorState != Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4420
    assert(_collectorState == AbortablePreclean,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4421
           "Spontaneous state transition?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4422
    _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4423
  } // Else, a foreground collection completed this CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4424
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4425
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4426
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4427
// Respond to an Eden sampling opportunity
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4428
void CMSCollector::sample_eden() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4429
  // Make sure a young gc cannot sneak in between our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4430
  // reading and recording of a sample.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4431
  assert(Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4432
         "Only the cms thread may collect Eden samples");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4433
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4434
         "Should collect samples while holding CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4435
  if (!_start_sampling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4436
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4437
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4438
  if (_eden_chunk_array) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4439
    if (_eden_chunk_index < _eden_chunk_capacity) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4440
      _eden_chunk_array[_eden_chunk_index] = *_top_addr;   // take sample
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4441
      assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4442
             "Unexpected state of Eden");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4443
      // We'd like to check that what we just sampled is an oop-start address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4444
      // however, we cannot do that here since the object may not yet have been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4445
      // initialized. So we'll instead do the check when we _use_ this sample
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4446
      // later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4447
      if (_eden_chunk_index == 0 ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4448
          (pointer_delta(_eden_chunk_array[_eden_chunk_index],
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4449
                         _eden_chunk_array[_eden_chunk_index-1])
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4450
           >= CMSSamplingGrain)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4451
        _eden_chunk_index++;  // commit sample
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4452
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4453
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4454
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4455
  if ((_collectorState == AbortablePreclean) && !_abort_preclean) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4456
    size_t used = get_eden_used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4457
    size_t capacity = get_eden_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4458
    assert(used <= capacity, "Unexpected state of Eden");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4459
    if (used >  (capacity/100 * CMSScheduleRemarkEdenPenetration)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4460
      _abort_preclean = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4461
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4462
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4463
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4464
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4465
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4466
size_t CMSCollector::preclean_work(bool clean_refs, bool clean_survivor) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4467
  assert(_collectorState == Precleaning ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4468
         _collectorState == AbortablePreclean, "incorrect state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4469
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4470
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4471
  // Do one pass of scrubbing the discovered reference lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4472
  // to remove any reference objects with strongly-reachable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4473
  // referents.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4474
  if (clean_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4475
    ReferenceProcessor* rp = ref_processor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4476
    CMSPrecleanRefsYieldClosure yield_cl(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4477
    assert(rp->span().equals(_span), "Spans should be equal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4478
    CMSKeepAliveClosure keep_alive(this, _span, &_markBitMap,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4479
                                   &_markStack, &_revisitStack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4480
                                   true /* preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4481
    CMSDrainMarkingStackClosure complete_trace(this,
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  4482
                                   _span, &_markBitMap, &_markStack,
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  4483
                                   &keep_alive, true /* preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4484
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4485
    // We don't want this step to interfere with a young
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4486
    // collection because we don't want to take CPU
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4487
    // or memory bandwidth away from the young GC threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4488
    // (which may be as many as there are CPUs).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4489
    // Note that we don't need to protect ourselves from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4490
    // interference with mutators because they can't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4491
    // manipulate the discovered reference lists nor affect
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4492
    // the computed reachability of the referents, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4493
    // only properties manipulated by the precleaning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4494
    // of these reference lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4495
    stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4496
    CMSTokenSyncWithLocks x(true /* is cms thread */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4497
                            bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4498
    startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4499
    sample_eden();
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4500
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4501
    // The following will yield to allow foreground
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4502
    // collection to proceed promptly. XXX YSR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4503
    // The code in this method may need further
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4504
    // tweaking for better performance and some restructuring
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4505
    // for cleaner interfaces.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4506
    rp->preclean_discovered_references(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4507
          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
  4508
          &yield_cl, should_unload_classes());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4509
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4510
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4511
  if (clean_survivor) {  // preclean the active survivor space(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4512
    assert(_young_gen->kind() == Generation::DefNew ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4513
           _young_gen->kind() == Generation::ParNew ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4514
           _young_gen->kind() == Generation::ASParNew,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4515
         "incorrect type for cast");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4516
    DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4517
    PushAndMarkClosure pam_cl(this, _span, ref_processor(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4518
                             &_markBitMap, &_modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4519
                             &_markStack, &_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4520
                             true /* precleaning phase */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4521
    stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4522
    CMSTokenSyncWithLocks ts(true /* is cms thread */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4523
                             bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4524
    startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4525
    unsigned int before_count =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4526
      GenCollectedHeap::heap()->total_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4527
    SurvivorSpacePrecleanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4528
      sss_cl(this, _span, &_markBitMap, &_markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4529
             &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
  4530
    DEBUG_ONLY(RememberKlassesChecker mx(should_unload_classes());)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4531
    dng->from()->object_iterate_careful(&sss_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4532
    dng->to()->object_iterate_careful(&sss_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4533
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4534
  MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4535
    mrias_cl(_span, ref_processor(), &_markBitMap, &_modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4536
             &_markStack, &_revisitStack, this, CMSYield,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4537
             true /* precleaning phase */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4538
  // CAUTION: The following closure has persistent state that may need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4539
  // be reset upon a decrease in the sequence of addresses it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4540
  // processes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4541
  ScanMarkedObjectsAgainCarefullyClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4542
    smoac_cl(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4543
      &_markBitMap, &_markStack, &_revisitStack, &mrias_cl, CMSYield);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4544
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4545
  // Preclean dirty cards in ModUnionTable and CardTable using
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4546
  // appropriate convergence criterion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4547
  // repeat CMSPrecleanIter times unless we find that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4548
  // we are losing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4549
  assert(CMSPrecleanIter < 10, "CMSPrecleanIter is too large");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4550
  assert(CMSPrecleanNumerator < CMSPrecleanDenominator,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4551
         "Bad convergence multiplier");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4552
  assert(CMSPrecleanThreshold >= 100,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4553
         "Unreasonably low CMSPrecleanThreshold");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4554
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4555
  size_t numIter, cumNumCards, lastNumCards, curNumCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4556
  for (numIter = 0, cumNumCards = lastNumCards = curNumCards = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4557
       numIter < CMSPrecleanIter;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4558
       numIter++, lastNumCards = curNumCards, cumNumCards += curNumCards) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4559
    curNumCards  = preclean_mod_union_table(_cmsGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4560
    if (CMSPermGenPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4561
      curNumCards  += preclean_mod_union_table(_permGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4562
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4563
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4564
      gclog_or_tty->print(" (modUnionTable: %d cards)", curNumCards);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4565
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4566
    // Either there are very few dirty cards, so re-mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4567
    // pause will be small anyway, or our pre-cleaning isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4568
    // that much faster than the rate at which cards are being
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4569
    // dirtied, so we might as well stop and re-mark since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4570
    // precleaning won't improve our re-mark time by much.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4571
    if (curNumCards <= CMSPrecleanThreshold ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4572
        (numIter > 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4573
         (curNumCards * CMSPrecleanDenominator >
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4574
         lastNumCards * CMSPrecleanNumerator))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4575
      numIter++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4576
      cumNumCards += curNumCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4577
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4578
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4579
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4580
  curNumCards = preclean_card_table(_cmsGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4581
  if (CMSPermGenPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4582
    curNumCards += preclean_card_table(_permGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4583
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4584
  cumNumCards += curNumCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4585
  if (PrintGCDetails && PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4586
    gclog_or_tty->print_cr(" (cardTable: %d cards, re-scanned %d cards, %d iterations)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4587
                  curNumCards, cumNumCards, numIter);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4588
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4589
  return cumNumCards;   // as a measure of useful work done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4590
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4591
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4592
// PRECLEANING NOTES:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4593
// Precleaning involves:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4594
// . reading the bits of the modUnionTable and clearing the set bits.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4595
// . For the cards corresponding to the set bits, we scan the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4596
//   objects on those cards. This means we need the free_list_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4597
//   so that we can safely iterate over the CMS space when scanning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4598
//   for oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4599
// . When we scan the objects, we'll be both reading and setting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4600
//   marks in the marking bit map, so we'll need the marking bit map.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4601
// . For protecting _collector_state transitions, we take the CGC_lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4602
//   Note that any races in the reading of of card table entries by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4603
//   CMS thread on the one hand and the clearing of those entries by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4604
//   VM thread or the setting of those entries by the mutator threads on the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4605
//   other are quite benign. However, for efficiency it makes sense to keep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4606
//   the VM thread from racing with the CMS thread while the latter is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4607
//   dirty card info to the modUnionTable. We therefore also use the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4608
//   CGC_lock to protect the reading of the card table and the mod union
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4609
//   table by the CM thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4610
// . We run concurrently with mutator updates, so scanning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4611
//   needs to be done carefully  -- we should not try to scan
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4612
//   potentially uninitialized objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4613
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4614
// Locking strategy: While holding the CGC_lock, we scan over and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4615
// reset a maximal dirty range of the mod union / card tables, then lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4616
// the free_list_lock and bitmap lock to do a full marking, then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4617
// release these locks; and repeat the cycle. This allows for a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4618
// certain amount of fairness in the sharing of these locks between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4619
// the CMS collector on the one hand, and the VM thread and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4620
// mutators on the other.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4621
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4622
// NOTE: preclean_mod_union_table() and preclean_card_table()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4623
// further below are largely identical; if you need to modify
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4624
// one of these methods, please check the other method too.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4625
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4626
size_t CMSCollector::preclean_mod_union_table(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4627
  ConcurrentMarkSweepGeneration* gen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4628
  ScanMarkedObjectsAgainCarefullyClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4629
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4630
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4631
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4632
  // Turn off checking for this method but turn it back on
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4633
  // selectively.  There are yield points in this method
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4634
  // but it is difficult to turn the checking off just around
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4635
  // the yield points.  It is simpler to selectively turn
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4636
  // it on.
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4637
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4638
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4639
  // strategy: starting with the first card, accumulate contiguous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4640
  // ranges of dirty cards; clear these cards, then scan the region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4641
  // covered by these cards.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4642
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4643
  // Since all of the MUT is committed ahead, we can just use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4644
  // that, in case the generations expand while we are precleaning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4645
  // It might also be fine to just use the committed part of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4646
  // generation, but we might potentially miss cards when the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4647
  // generation is rapidly expanding while we are in the midst
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4648
  // of precleaning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4649
  HeapWord* startAddr = gen->reserved().start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4650
  HeapWord* endAddr   = gen->reserved().end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4651
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4652
  cl->setFreelistLock(gen->freelistLock());   // needed for yielding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4653
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4654
  size_t numDirtyCards, cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4655
  HeapWord *nextAddr, *lastAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4656
  for (cumNumDirtyCards = numDirtyCards = 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4657
       nextAddr = lastAddr = startAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4658
       nextAddr < endAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4659
       nextAddr = lastAddr, cumNumDirtyCards += numDirtyCards) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4660
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4661
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4662
    HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4663
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4664
    MemRegion dirtyRegion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4665
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4666
      stopTimer();
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4667
      // Potential yield point
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4668
      CMSTokenSync ts(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4669
      startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4670
      sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4671
      // Get dirty region starting at nextOffset (inclusive),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4672
      // simultaneously clearing it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4673
      dirtyRegion =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4674
        _modUnionTable.getAndClearMarkedRegion(nextAddr, endAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4675
      assert(dirtyRegion.start() >= nextAddr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4676
             "returned region inconsistent?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4677
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4678
    // Remember where the next search should begin.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4679
    // The returned region (if non-empty) is a right open interval,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4680
    // so lastOffset is obtained from the right end of that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4681
    // interval.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4682
    lastAddr = dirtyRegion.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4683
    // Should do something more transparent and less hacky XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4684
    numDirtyCards =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4685
      _modUnionTable.heapWordDiffToOffsetDiff(dirtyRegion.word_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4686
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4687
    // We'll scan the cards in the dirty region (with periodic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4688
    // yields for foreground GC as needed).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4689
    if (!dirtyRegion.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4690
      assert(numDirtyCards > 0, "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4691
      HeapWord* stop_point = NULL;
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4692
      stopTimer();
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4693
      // Potential yield point
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4694
      CMSTokenSyncWithLocks ts(true, gen->freelistLock(),
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4695
                               bitMapLock());
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4696
      startTimer();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4697
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4698
        verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4699
        verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4700
        sample_eden();
4738
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4574
diff changeset
  4701
        DEBUG_ONLY(RememberKlassesChecker mx(should_unload_classes());)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4702
        stop_point =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4703
          gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4704
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4705
      if (stop_point != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4706
        // The careful iteration stopped early either because it found an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4707
        // uninitialized object, or because we were in the midst of an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4708
        // "abortable preclean", which should now be aborted. Redirty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4709
        // the bits corresponding to the partially-scanned or unscanned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4710
        // cards. We'll either restart at the next block boundary or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4711
        // abort the preclean.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4712
        assert((CMSPermGenPrecleaningEnabled && (gen == _permGen)) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4713
               (_collectorState == AbortablePreclean && should_abort_preclean()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4714
               "Unparsable objects should only be in perm gen.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4715
        _modUnionTable.mark_range(MemRegion(stop_point, dirtyRegion.end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4716
        if (should_abort_preclean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4717
          break; // out of preclean loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4718
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4719
          // Compute the next address at which preclean should pick up;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4720
          // might need bitMapLock in order to read P-bits.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4721
          lastAddr = next_card_start_after_block(stop_point);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4722
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4723
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4724
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4725
      assert(lastAddr == endAddr, "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4726
      assert(numDirtyCards == 0, "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4727
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4728
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4729
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4730
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4731
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4732
  return cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4733
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4734
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4735
// NOTE: preclean_mod_union_table() above and preclean_card_table()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4736
// below are largely identical; if you need to modify
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4737
// one of these methods, please check the other method too.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4738
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4739
size_t CMSCollector::preclean_card_table(ConcurrentMarkSweepGeneration* gen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4740
  ScanMarkedObjectsAgainCarefullyClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4741
  // strategy: it's similar to precleamModUnionTable above, in that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4742
  // we accumulate contiguous ranges of dirty cards, mark these cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4743
  // precleaned, then scan the region covered by these cards.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4744
  HeapWord* endAddr   = (HeapWord*)(gen->_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4745
  HeapWord* startAddr = (HeapWord*)(gen->_virtual_space.low());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4746
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4747
  cl->setFreelistLock(gen->freelistLock());   // needed for yielding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4748
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4749
  size_t numDirtyCards, cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4750
  HeapWord *lastAddr, *nextAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4751
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4752
  for (cumNumDirtyCards = numDirtyCards = 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4753
       nextAddr = lastAddr = startAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4754
       nextAddr < endAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4755
       nextAddr = lastAddr, cumNumDirtyCards += numDirtyCards) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4756
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4757
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4758
    HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4759
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4760
    MemRegion dirtyRegion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4761
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4762
      // See comments in "Precleaning notes" above on why we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4763
      // do this locking. XXX Could the locking overheads be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4764
      // too high when dirty cards are sparse? [I don't think so.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4765
      stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4766
      CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4767
      startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4768
      sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4769
      // Get and clear dirty region from card table
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4770
      dirtyRegion = _ct->ct_bs()->dirty_card_range_after_reset(
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4771
                                    MemRegion(nextAddr, endAddr),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4772
                                    true,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4773
                                    CardTableModRefBS::precleaned_card_val());
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4774
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4775
      assert(dirtyRegion.start() >= nextAddr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4776
             "returned region inconsistent?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4777
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4778
    lastAddr = dirtyRegion.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4779
    numDirtyCards =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4780
      dirtyRegion.word_size()/CardTableModRefBS::card_size_in_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4781
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4782
    if (!dirtyRegion.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4783
      stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4784
      CMSTokenSyncWithLocks ts(true, gen->freelistLock(), bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4785
      startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4786
      sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4787
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4788
      verify_overflow_empty();
4738
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4574
diff changeset
  4789
      DEBUG_ONLY(RememberKlassesChecker mx(should_unload_classes());)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4790
      HeapWord* stop_point =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4791
        gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4792
      if (stop_point != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4793
        // The careful iteration stopped early because it found an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4794
        // uninitialized object.  Redirty the bits corresponding to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4795
        // partially-scanned or unscanned cards, and start again at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4796
        // next block boundary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4797
        assert(CMSPermGenPrecleaningEnabled ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4798
               (_collectorState == AbortablePreclean && should_abort_preclean()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4799
               "Unparsable objects should only be in perm gen.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4800
        _ct->ct_bs()->invalidate(MemRegion(stop_point, dirtyRegion.end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4801
        if (should_abort_preclean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4802
          break; // out of preclean loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4803
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4804
          // Compute the next address at which preclean should pick up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4805
          lastAddr = next_card_start_after_block(stop_point);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4806
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4807
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4808
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4809
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4810
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4811
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4812
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4813
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4814
  return cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4815
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4816
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4817
void CMSCollector::checkpointRootsFinal(bool asynch,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4818
  bool clear_all_soft_refs, bool init_mark_was_synchronous) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4819
  assert(_collectorState == FinalMarking, "incorrect state transition?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4820
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4821
  // world is stopped at this checkpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4822
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4823
         "world should be stopped");
6245
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  4824
  TraceCMSMemoryManagerStats tms(_collectorState);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4825
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4826
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4827
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4828
  SpecializationStats::clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4829
  if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4830
    gclog_or_tty->print("[YG occupancy: "SIZE_FORMAT" K ("SIZE_FORMAT" K)]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4831
                        _young_gen->used() / K,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4832
                        _young_gen->capacity() / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4833
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4834
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4835
    if (CMSScavengeBeforeRemark) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4836
      GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4837
      // Temporarily set flag to false, GCH->do_collection will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4838
      // expect it to be false and set to true
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4839
      FlagSetting fl(gch->_is_gc_active, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4840
      NOT_PRODUCT(TraceTime t("Scavenge-Before-Remark",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4841
        PrintGCDetails && Verbose, true, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4842
      int level = _cmsGen->level() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4843
      if (level >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4844
        gch->do_collection(true,        // full (i.e. force, see below)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4845
                           false,       // !clear_all_soft_refs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4846
                           0,           // size
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4847
                           false,       // is_tlab
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4848
                           level        // max_level
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4849
                          );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4850
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4851
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4852
    FreelistLocker x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4853
    MutexLockerEx y(bitMapLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4854
                    Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4855
    assert(!init_mark_was_synchronous, "but that's impossible!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4856
    checkpointRootsFinalWork(asynch, clear_all_soft_refs, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4857
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4858
    // already have all the locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4859
    checkpointRootsFinalWork(asynch, clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4860
                             init_mark_was_synchronous);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4861
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4862
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4863
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4864
  SpecializationStats::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4865
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4866
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4867
void CMSCollector::checkpointRootsFinalWork(bool asynch,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4868
  bool clear_all_soft_refs, bool init_mark_was_synchronous) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4869
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4870
  NOT_PRODUCT(TraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4871
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4872
  assert(haveFreelistLocks(), "must have free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4873
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4874
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4875
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4876
    size_policy()->checkpoint_roots_final_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4877
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4878
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4879
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4880
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4881
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4882
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4883
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  4884
  if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4885
    CodeCache::gc_prologue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4886
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4887
  assert(haveFreelistLocks(), "must have free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4888
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4889
4738
25586a89c1c3 6895236: CMS: cmsOopClosures.inline.hpp:43 assert(..., "Should remember klasses in this context")
jmasa
parents: 4574
diff changeset
  4890
  DEBUG_ONLY(RememberKlassesChecker fmx(should_unload_classes());)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4891
  if (!init_mark_was_synchronous) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4892
    // We might assume that we need not fill TLAB's when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4893
    // CMSScavengeBeforeRemark is set, because we may have just done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4894
    // a scavenge which would have filled all TLAB's -- and besides
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4895
    // Eden would be empty. This however may not always be the case --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4896
    // for instance although we asked for a scavenge, it may not have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4897
    // happened because of a JNI critical section. We probably need
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4898
    // a policy for deciding whether we can in that case wait until
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4899
    // the critical section releases and then do the remark following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4900
    // the scavenge, and skip it here. In the absence of that policy,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4901
    // or of an indication of whether the scavenge did indeed occur,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4902
    // we cannot rely on TLAB's having been filled and must do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4903
    // so here just in case a scavenge did not happen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4904
    gch->ensure_parsability(false);  // fill TLAB's, but no need to retire them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4905
    // Update the saved marks which may affect the root scans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4906
    gch->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4907
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4908
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4909
      COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4910
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4911
      // Note on the role of the mod union table:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4912
      // Since the marker in "markFromRoots" marks concurrently with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4913
      // mutators, it is possible for some reachable objects not to have been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4914
      // scanned. For instance, an only reference to an object A was
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4915
      // placed in object B after the marker scanned B. Unless B is rescanned,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4916
      // A would be collected. Such updates to references in marked objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4917
      // are detected via the mod union table which is the set of all cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4918
      // dirtied since the first checkpoint in this GC cycle and prior to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4919
      // the most recent young generation GC, minus those cleaned up by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4920
      // concurrent precleaning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4921
      if (CMSParallelRemarkEnabled && ParallelGCThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4922
        TraceTime t("Rescan (parallel) ", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4923
        do_remark_parallel();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4924
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4925
        TraceTime t("Rescan (non-parallel) ", PrintGCDetails, false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4926
                    gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4927
        do_remark_non_parallel();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4928
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4929
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4930
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4931
    assert(!asynch, "Can't have init_mark_was_synchronous in asynch mode");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4932
    // The initial mark was stop-world, so there's no rescanning to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4933
    // do; go straight on to the next step below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4934
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4935
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4936
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4937
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4938
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4939
    NOT_PRODUCT(TraceTime ts("refProcessingWork", PrintGCDetails, false, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4940
    refProcessingWork(asynch, clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4941
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4942
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4943
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4944
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  4945
  if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4946
    CodeCache::gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4947
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4948
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4949
  // If we encountered any (marking stack / work queue) overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4950
  // events during the current CMS cycle, take appropriate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4951
  // remedial measures, where possible, so as to try and avoid
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4952
  // recurrence of that condition.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4953
  assert(_markStack.isEmpty(), "No grey objects");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4954
  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
  4955
                     _ser_kac_ovflw        + _ser_kac_preclean_ovflw;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4956
  if (ser_ovflw > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4957
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4958
      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
  4959
        "(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
  4960
        ", kac_preclean="SIZE_FORMAT")",
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4961
        _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
  4962
        _ser_kac_ovflw, _ser_kac_preclean_ovflw);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4963
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4964
    _markStack.expand();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4965
    _ser_pmc_remark_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4966
    _ser_pmc_preclean_ovflw = 0;
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  4967
    _ser_kac_preclean_ovflw = 0;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4968
    _ser_kac_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4969
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4970
  if (_par_pmc_remark_ovflw > 0 || _par_kac_ovflw > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4971
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4972
      gclog_or_tty->print_cr("Work queue overflow (benign) "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4973
        "(pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT")",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4974
        _par_pmc_remark_ovflw, _par_kac_ovflw);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4975
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4976
    _par_pmc_remark_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4977
    _par_kac_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4978
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4979
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4980
     if (_markStack._hit_limit > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4981
       gclog_or_tty->print_cr(" (benign) Hit max stack size limit ("SIZE_FORMAT")",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4982
                              _markStack._hit_limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4983
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4984
     if (_markStack._failed_double > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4985
       gclog_or_tty->print_cr(" (benign) Failed stack doubling ("SIZE_FORMAT"),"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4986
                              " current capacity "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4987
                              _markStack._failed_double,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4988
                              _markStack.capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4989
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4990
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4991
  _markStack._hit_limit = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4992
  _markStack._failed_double = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4993
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4994
  // Check that all the klasses have been checked
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4995
  assert(_revisitStack.isEmpty(), "Not all klasses revisited");
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4996
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4997
  if ((VerifyAfterGC || VerifyDuringGC) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4998
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4999
    verify_after_remark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5000
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5001
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5002
  // Change under the freelistLocks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5003
  _collectorState = Sweeping;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5004
  // Call isAllClear() under bitMapLock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5005
  assert(_modUnionTable.isAllClear(), "Should be clear by end of the"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5006
    " final marking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5007
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5008
    size_policy()->checkpoint_roots_final_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5009
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5010
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5011
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5012
// Parallel remark task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5013
class CMSParRemarkTask: public AbstractGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5014
  CMSCollector* _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5015
  WorkGang*     _workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5016
  int           _n_workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5017
  CompactibleFreeListSpace* _cms_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5018
  CompactibleFreeListSpace* _perm_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5019
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5020
  // The per-thread work queues, available here for stealing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5021
  OopTaskQueueSet*       _task_queues;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5022
  ParallelTaskTerminator _term;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5023
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5024
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5025
  CMSParRemarkTask(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5026
                   CompactibleFreeListSpace* cms_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5027
                   CompactibleFreeListSpace* perm_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5028
                   int n_workers, WorkGang* workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5029
                   OopTaskQueueSet* task_queues):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5030
    AbstractGangTask("Rescan roots and grey objects in parallel"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5031
    _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5032
    _cms_space(cms_space), _perm_space(perm_space),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5033
    _n_workers(n_workers),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5034
    _workers(workers),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5035
    _task_queues(task_queues),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5036
    _term(workers->total_workers(), task_queues) { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5037
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5038
  OopTaskQueueSet* task_queues() { return _task_queues; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5040
  OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5041
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5042
  ParallelTaskTerminator* terminator() { return &_term; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5043
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5044
  void work(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5045
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5046
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5047
  // Work method in support of parallel rescan ... of young gen spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5048
  void do_young_space_rescan(int i, Par_MarkRefsIntoAndScanClosure* cl,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5049
                             ContiguousSpace* space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5050
                             HeapWord** chunk_array, size_t chunk_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5051
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5052
  // ... of  dirty cards in old space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5053
  void do_dirty_card_rescan_tasks(CompactibleFreeListSpace* sp, int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5054
                                  Par_MarkRefsIntoAndScanClosure* cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5055
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5056
  // ... work stealing for the above
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5057
  void do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl, int* seed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5058
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5059
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5060
void CMSParRemarkTask::work(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5061
  elapsedTimer _timer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5062
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5063
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5064
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5065
  // ---------- rescan from roots --------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5066
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5067
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5068
  Par_MarkRefsIntoAndScanClosure par_mrias_cl(_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5069
    _collector->_span, _collector->ref_processor(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5070
    &(_collector->_markBitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5071
    work_queue(i), &(_collector->_revisitStack));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5072
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5073
  // Rescan young gen roots first since these are likely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5074
  // coarsely partitioned and may, on that account, constitute
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5075
  // the critical path; thus, it's best to start off that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5076
  // work first.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5077
  // ---------- young gen roots --------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5078
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5079
    DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5080
    EdenSpace* eden_space = dng->eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5081
    ContiguousSpace* from_space = dng->from();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5082
    ContiguousSpace* to_space   = dng->to();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5083
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5084
    HeapWord** eca = _collector->_eden_chunk_array;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5085
    size_t     ect = _collector->_eden_chunk_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5086
    HeapWord** sca = _collector->_survivor_chunk_array;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5087
    size_t     sct = _collector->_survivor_chunk_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5088
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5089
    assert(ect <= _collector->_eden_chunk_capacity, "out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5090
    assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5091
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5092
    do_young_space_rescan(i, &par_mrias_cl, to_space, NULL, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5093
    do_young_space_rescan(i, &par_mrias_cl, from_space, sca, sct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5094
    do_young_space_rescan(i, &par_mrias_cl, eden_space, eca, ect);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5095
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5096
    _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5097
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5098
      gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5099
        "Finished young gen rescan work in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5100
        i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5101
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5102
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5103
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5104
  // ---------- remaining roots --------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5105
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5106
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5107
  gch->gen_process_strong_roots(_collector->_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5108
                                false,     // yg was scanned above
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5109
                                false,     // this is parallel code
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5110
                                true,      // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5111
                                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
  5112
                                &par_mrias_cl,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5113
                                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
  5114
                                NULL);
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5115
  assert(_collector->should_unload_classes()
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5116
         || (_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
  5117
         "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
  5118
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5119
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5120
    gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5121
      "Finished remaining root rescan work in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5122
      i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5123
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5124
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5125
  // ---------- rescan dirty cards ------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5126
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5127
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5128
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5129
  // Do the rescan tasks for each of the two spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5130
  // (cms_space and perm_space) in turn.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5131
  do_dirty_card_rescan_tasks(_cms_space, i, &par_mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5132
  do_dirty_card_rescan_tasks(_perm_space, i, &par_mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5133
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5134
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5135
    gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5136
      "Finished dirty card rescan work in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5137
      i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5138
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5139
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5140
  // ---------- steal work from other threads ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5141
  // ---------- ... and drain overflow list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5142
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5143
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5144
  do_work_steal(i, &par_mrias_cl, _collector->hash_seed(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5145
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5146
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5147
    gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5148
      "Finished work stealing in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5149
      i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5150
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5151
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5152
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5153
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5154
CMSParRemarkTask::do_young_space_rescan(int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5155
  Par_MarkRefsIntoAndScanClosure* cl, ContiguousSpace* space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5156
  HeapWord** chunk_array, size_t chunk_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5157
  // Until all tasks completed:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5158
  // . claim an unclaimed task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5159
  // . compute region boundaries corresponding to task claimed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5160
  //   using chunk_array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5161
  // . par_oop_iterate(cl) over that region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5162
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5163
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5164
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5165
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5166
  SequentialSubTasksDone* pst = space->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5167
  assert(pst->valid(), "Uninitialized use?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5168
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5169
  int nth_task = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5170
  int n_tasks  = pst->n_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5171
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5172
  HeapWord *start, *end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5173
  while (!pst->is_task_claimed(/* reference */ nth_task)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5174
    // We claimed task # nth_task; compute its boundaries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5175
    if (chunk_top == 0) {  // no samples were taken
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5176
      assert(nth_task == 0 && n_tasks == 1, "Can have only 1 EdenSpace task");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5177
      start = space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5178
      end   = space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5179
    } else if (nth_task == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5180
      start = space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5181
      end   = chunk_array[nth_task];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5182
    } else if (nth_task < (jint)chunk_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5183
      assert(nth_task >= 1, "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5184
      start = chunk_array[nth_task - 1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5185
      end   = chunk_array[nth_task];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5186
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5187
      assert(nth_task == (jint)chunk_top, "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5188
      start = chunk_array[chunk_top - 1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5189
      end   = space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5190
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5191
    MemRegion mr(start, end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5192
    // Verify that mr is in space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5193
    assert(mr.is_empty() || space->used_region().contains(mr),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5194
           "Should be in space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5195
    // Verify that "start" is an object boundary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5196
    assert(mr.is_empty() || oop(mr.start())->is_oop(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5197
           "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5198
    space->par_oop_iterate(mr, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5199
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5200
  pst->all_tasks_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5201
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5202
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5203
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5204
CMSParRemarkTask::do_dirty_card_rescan_tasks(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5205
  CompactibleFreeListSpace* sp, int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5206
  Par_MarkRefsIntoAndScanClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5207
  // Until all tasks completed:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5208
  // . claim an unclaimed task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5209
  // . compute region boundaries corresponding to task claimed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5210
  // . transfer dirty bits ct->mut for that region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5211
  // . apply rescanclosure to dirty mut bits for that region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5212
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5213
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5214
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5215
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5216
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5217
  ModUnionClosure modUnionClosure(&(_collector->_modUnionTable));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5218
  // CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! CAUTION!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5219
  // CAUTION: This closure has state that persists across calls to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5220
  // the work method dirty_range_iterate_clear() in that it has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5221
  // imbedded in it a (subtype of) UpwardsObjectClosure. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5222
  // use of that state in the imbedded UpwardsObjectClosure instance
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5223
  // assumes that the cards are always iterated (even if in parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5224
  // by several threads) in monotonically increasing order per each
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5225
  // thread. This is true of the implementation below which picks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5226
  // card ranges (chunks) in monotonically increasing order globally
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5227
  // and, a-fortiori, in monotonically increasing order per thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5228
  // (the latter order being a subsequence of the former).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5229
  // If the work code below is ever reorganized into a more chaotic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5230
  // work-partitioning form than the current "sequential tasks"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5231
  // paradigm, the use of that persistent state will have to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5232
  // revisited and modified appropriately. See also related
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5233
  // bug 4756801 work on which should examine this code to make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5234
  // sure that the changes there do not run counter to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5235
  // assumptions made here and necessary for correctness and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5236
  // efficiency. Note also that this code might yield inefficient
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5237
  // behaviour in the case of very large objects that span one or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5238
  // more work chunks. Such objects would potentially be scanned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5239
  // several times redundantly. Work on 4756801 should try and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5240
  // address that performance anomaly if at all possible. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5241
  MemRegion  full_span  = _collector->_span;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5242
  CMSBitMap* bm    = &(_collector->_markBitMap);     // shared
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5243
  CMSMarkStack* rs = &(_collector->_revisitStack);   // shared
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5244
  MarkFromDirtyCardsClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5245
    greyRescanClosure(_collector, full_span, // entire span of interest
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5246
                      sp, bm, work_q, rs, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5247
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5248
  SequentialSubTasksDone* pst = sp->conc_par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5249
  assert(pst->valid(), "Uninitialized use?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5250
  int nth_task = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5251
  const int alignment = CardTableModRefBS::card_size * BitsPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5252
  MemRegion span = sp->used_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5253
  HeapWord* start_addr = span.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5254
  HeapWord* end_addr = (HeapWord*)round_to((intptr_t)span.end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5255
                                           alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5256
  const size_t chunk_size = sp->rescan_task_size(); // in HeapWord units
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5257
  assert((HeapWord*)round_to((intptr_t)start_addr, alignment) ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5258
         start_addr, "Check alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5259
  assert((size_t)round_to((intptr_t)chunk_size, alignment) ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5260
         chunk_size, "Check alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5261
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5262
  while (!pst->is_task_claimed(/* reference */ nth_task)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5263
    // Having claimed the nth_task, compute corresponding mem-region,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5264
    // which is a-fortiori aligned correctly (i.e. at a MUT bopundary).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5265
    // The alignment restriction ensures that we do not need any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5266
    // synchronization with other gang-workers while setting or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5267
    // clearing bits in thus chunk of the MUT.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5268
    MemRegion this_span = MemRegion(start_addr + nth_task*chunk_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5269
                                    start_addr + (nth_task+1)*chunk_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5270
    // The last chunk's end might be way beyond end of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5271
    // used region. In that case pull back appropriately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5272
    if (this_span.end() > end_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5273
      this_span.set_end(end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5274
      assert(!this_span.is_empty(), "Program logic (calculation of n_tasks)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5275
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5276
    // Iterate over the dirty cards covering this chunk, marking them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5277
    // precleaned, and setting the corresponding bits in the mod union
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5278
    // table. Since we have been careful to partition at Card and MUT-word
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5279
    // boundaries no synchronization is needed between parallel threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5280
    _collector->_ct->ct_bs()->dirty_card_iterate(this_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5281
                                                 &modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5283
    // Having transferred these marks into the modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5284
    // rescan the marked objects on the dirty cards in the modUnionTable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5285
    // Even if this is at a synchronous collection, the initial marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5286
    // may have been done during an asynchronous collection so there
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5287
    // may be dirty bits in the mod-union table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5288
    _collector->_modUnionTable.dirty_range_iterate_clear(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5289
                  this_span, &greyRescanClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5290
    _collector->_modUnionTable.verifyNoOneBitsInRange(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5291
                                 this_span.start(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5292
                                 this_span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5293
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5294
  pst->all_tasks_completed();  // declare that i am done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5295
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5296
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5297
// . see if we can share work_queues with ParNew? XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5298
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5299
CMSParRemarkTask::do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5300
                                int* seed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5301
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5302
  NOT_PRODUCT(int num_steals = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5303
  oop obj_to_scan;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5304
  CMSBitMap* bm = &(_collector->_markBitMap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5305
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5306
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5307
    // Completely finish any left over work from (an) earlier round(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5308
    cl->trim_queue(0);
2346
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  5309
    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
  5310
                                         (size_t)ParGCDesiredObjsFromOverflowList);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5311
    // Now check if there's any work in the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5312
    if (_collector->par_take_from_overflow_list(num_from_overflow_list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5313
                                                work_q)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5314
      // found something in global overflow list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5315
      // not yet ready to go stealing work from others.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5316
      // We'd like to assert(work_q->size() != 0, ...)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5317
      // because we just took work from the overflow list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5318
      // but of course we can't since all of that could have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5319
      // been already stolen from us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5320
      // "He giveth and He taketh away."
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5321
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5322
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5323
    // Verify that we have no work before we resort to stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5324
    assert(work_q->size() == 0, "Have work, shouldn't steal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5325
    // Try to steal from other queues that have work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5326
    if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5327
      NOT_PRODUCT(num_steals++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5328
      assert(obj_to_scan->is_oop(), "Oops, not an oop!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5329
      assert(bm->isMarked((HeapWord*)obj_to_scan), "Stole an unmarked oop?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5330
      // Do scanning work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5331
      obj_to_scan->oop_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5332
      // Loop around, finish this work, and try to steal some more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5333
    } else if (terminator()->offer_termination()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5334
        break;  // nirvana from the infinite cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5335
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5336
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5337
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5338
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5339
      gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5340
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5341
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5342
  assert(work_q->size() == 0 && _collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5343
         "Else our work is not yet done");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5344
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5345
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5346
// Return a thread-local PLAB recording array, as appropriate.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5347
void* CMSCollector::get_data_recorder(int thr_num) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5348
  if (_survivor_plab_array != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5349
      (CMSPLABRecordAlways ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5350
       (_collectorState > Marking && _collectorState < FinalMarking))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5351
    assert(thr_num < (int)ParallelGCThreads, "thr_num is out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5352
    ChunkArray* ca = &_survivor_plab_array[thr_num];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5353
    ca->reset();   // clear it so that fresh data is recorded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5354
    return (void*) ca;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5355
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5356
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5357
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5358
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5359
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5360
// Reset all the thread-local PLAB recording arrays
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5361
void CMSCollector::reset_survivor_plab_arrays() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5362
  for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5363
    _survivor_plab_array[i].reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5364
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5365
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5366
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5367
// Merge the per-thread plab arrays into the global survivor chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5368
// array which will provide the partitioning of the survivor space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5369
// for CMS rescan.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5370
void CMSCollector::merge_survivor_plab_arrays(ContiguousSpace* surv) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5371
  assert(_survivor_plab_array  != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5372
  assert(_survivor_chunk_array != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5373
  assert(_collectorState == FinalMarking, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5374
  for (uint j = 0; j < ParallelGCThreads; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5375
    _cursor[j] = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5376
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5377
  HeapWord* top = surv->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5378
  size_t i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5379
  for (i = 0; i < _survivor_chunk_capacity; i++) {  // all sca entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5380
    HeapWord* min_val = top;          // Higher than any PLAB address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5381
    uint      min_tid = 0;            // position of min_val this round
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5382
    for (uint j = 0; j < ParallelGCThreads; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5383
      ChunkArray* cur_sca = &_survivor_plab_array[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5384
      if (_cursor[j] == cur_sca->end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5385
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5386
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5387
      assert(_cursor[j] < cur_sca->end(), "ctl pt invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5388
      HeapWord* cur_val = cur_sca->nth(_cursor[j]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5389
      assert(surv->used_region().contains(cur_val), "Out of bounds value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5390
      if (cur_val < min_val) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5391
        min_tid = j;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5392
        min_val = cur_val;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5393
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5394
        assert(cur_val < top, "All recorded addresses should be less");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5395
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5396
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5397
    // At this point min_val and min_tid are respectively
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5398
    // the least address in _survivor_plab_array[j]->nth(_cursor[j])
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5399
    // and the thread (j) that witnesses that address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5400
    // We record this address in the _survivor_chunk_array[i]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5401
    // and increment _cursor[min_tid] prior to the next round i.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5402
    if (min_val == top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5403
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5404
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5405
    _survivor_chunk_array[i] = min_val;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5406
    _cursor[min_tid]++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5407
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5408
  // We are all done; record the size of the _survivor_chunk_array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5409
  _survivor_chunk_index = i; // exclusive: [0, i)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5410
  if (PrintCMSStatistics > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5411
    gclog_or_tty->print(" (Survivor:" SIZE_FORMAT "chunks) ", i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5412
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5413
  // Verify that we used up all the recorded entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5414
  #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5415
    size_t total = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5416
    for (uint j = 0; j < ParallelGCThreads; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5417
      assert(_cursor[j] == _survivor_plab_array[j].end(), "Ctl pt invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5418
      total += _cursor[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5419
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5420
    assert(total == _survivor_chunk_index, "Ctl Pt Invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5421
    // Check that the merged array is in sorted order
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5422
    if (total > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5423
      for (size_t i = 0; i < total - 1; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5424
        if (PrintCMSStatistics > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5425
          gclog_or_tty->print(" (chunk" SIZE_FORMAT ":" INTPTR_FORMAT ") ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5426
                              i, _survivor_chunk_array[i]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5427
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5428
        assert(_survivor_chunk_array[i] < _survivor_chunk_array[i+1],
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5429
               "Not sorted");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5430
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5431
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5432
  #endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5433
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5434
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5435
// Set up the space's par_seq_tasks structure for work claiming
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5436
// for parallel rescan of young gen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5437
// See ParRescanTask where this is currently used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5438
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5439
CMSCollector::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5440
initialize_sequential_subtasks_for_young_gen_rescan(int n_threads) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5441
  assert(n_threads > 0, "Unexpected n_threads argument");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5442
  DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5443
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5444
  // Eden space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5445
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5446
    SequentialSubTasksDone* pst = dng->eden()->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5447
    assert(!pst->valid(), "Clobbering existing data?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5448
    // Each valid entry in [0, _eden_chunk_index) represents a task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5449
    size_t n_tasks = _eden_chunk_index + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5450
    assert(n_tasks == 1 || _eden_chunk_array != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5451
    pst->set_par_threads(n_threads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5452
    pst->set_n_tasks((int)n_tasks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5453
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5454
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5455
  // Merge the survivor plab arrays into _survivor_chunk_array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5456
  if (_survivor_plab_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5457
    merge_survivor_plab_arrays(dng->from());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5458
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5459
    assert(_survivor_chunk_index == 0, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5460
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5461
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5462
  // To space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5463
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5464
    SequentialSubTasksDone* pst = dng->to()->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5465
    assert(!pst->valid(), "Clobbering existing data?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5466
    pst->set_par_threads(n_threads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5467
    pst->set_n_tasks(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5468
    assert(pst->valid(), "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5469
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5470
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5471
  // From space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5472
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5473
    SequentialSubTasksDone* pst = dng->from()->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5474
    assert(!pst->valid(), "Clobbering existing data?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5475
    size_t n_tasks = _survivor_chunk_index + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5476
    assert(n_tasks == 1 || _survivor_chunk_array != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5477
    pst->set_par_threads(n_threads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5478
    pst->set_n_tasks((int)n_tasks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5479
    assert(pst->valid(), "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5480
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5481
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5482
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5483
// Parallel version of remark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5484
void CMSCollector::do_remark_parallel() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5485
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5486
  WorkGang* workers = gch->workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5487
  assert(workers != NULL, "Need parallel worker threads.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5488
  int n_workers = workers->total_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5489
  CompactibleFreeListSpace* cms_space  = _cmsGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5490
  CompactibleFreeListSpace* perm_space = _permGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5491
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5492
  CMSParRemarkTask tsk(this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5493
    cms_space, perm_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5494
    n_workers, workers, task_queues());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5495
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5496
  // Set up for parallel process_strong_roots work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5497
  gch->set_par_threads(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5498
  // We won't be iterating over the cards in the card table updating
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5499
  // the younger_gen cards, so we shouldn't call the following else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5500
  // the verification code as well as subsequent younger_refs_iterate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5501
  // code would get confused. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5502
  // gch->rem_set()->prepare_for_younger_refs_iterate(true); // parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5503
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5504
  // The young gen rescan work will not be done as part of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5505
  // process_strong_roots (which currently doesn't knw how to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5506
  // parallelize such a scan), but rather will be broken up into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5507
  // a set of parallel tasks (via the sampling that the [abortable]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5508
  // preclean phase did of EdenSpace, plus the [two] tasks of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5509
  // scanning the [two] survivor spaces. Further fine-grain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5510
  // parallelization of the scanning of the survivor spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5511
  // themselves, and of precleaning of the younger gen itself
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5512
  // is deferred to the future.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5513
  initialize_sequential_subtasks_for_young_gen_rescan(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5514
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5515
  // The dirty card rescan work is broken up into a "sequence"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5516
  // of parallel tasks (per constituent space) that are dynamically
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5517
  // claimed by the parallel threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5518
  cms_space->initialize_sequential_subtasks_for_rescan(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5519
  perm_space->initialize_sequential_subtasks_for_rescan(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5520
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5521
  // It turns out that even when we're using 1 thread, doing the work in a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5522
  // separate thread causes wide variance in run times.  We can't help this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5523
  // in the multi-threaded case, but we special-case n=1 here to get
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5524
  // repeatable measurements of the 1-thread overhead of the parallel code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5525
  if (n_workers > 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5526
    // Make refs discovery MT-safe
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5527
    ReferenceProcessorMTMutator mt(ref_processor(), true);
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5528
    GenCollectedHeap::StrongRootsScope srs(gch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5529
    workers->run_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5530
  } else {
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5531
    GenCollectedHeap::StrongRootsScope srs(gch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5532
    tsk.work(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5533
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5534
  gch->set_par_threads(0);  // 0 ==> non-parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5535
  // restore, single-threaded for now, any preserved marks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5536
  // as a result of work_q overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5537
  restore_preserved_marks_if_any();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5538
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5539
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5540
// Non-parallel version of remark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5541
void CMSCollector::do_remark_non_parallel() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5542
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5543
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5544
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5545
  MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5546
    mrias_cl(_span, ref_processor(), &_markBitMap, &_modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5547
             &_markStack, &_revisitStack, this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5548
             false /* should_yield */, false /* not precleaning */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5549
  MarkFromDirtyCardsClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5550
    markFromDirtyCardsClosure(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5551
                              NULL,  // space is set further below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5552
                              &_markBitMap, &_markStack, &_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5553
                              &mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5554
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5555
    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
  5556
    // 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
  5557
    // mod union table.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5558
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5559
      ModUnionClosure modUnionClosure(&_modUnionTable);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5560
      _ct->ct_bs()->dirty_card_iterate(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5561
                      _cmsGen->used_region(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5562
                      &modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5563
      _ct->ct_bs()->dirty_card_iterate(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5564
                      _permGen->used_region(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5565
                      &modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5566
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5567
    // Having transferred these marks into the modUnionTable, we just need
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5568
    // to rescan the marked objects on the dirty cards in the modUnionTable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5569
    // The initial marking may have been done during an asynchronous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5570
    // collection so there may be dirty bits in the mod-union table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5571
    const int alignment =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5572
      CardTableModRefBS::card_size * BitsPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5573
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5574
      // ... First handle dirty cards in CMS gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5575
      markFromDirtyCardsClosure.set_space(_cmsGen->cmsSpace());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5576
      MemRegion ur = _cmsGen->used_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5577
      HeapWord* lb = ur.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5578
      HeapWord* ub = (HeapWord*)round_to((intptr_t)ur.end(), alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5579
      MemRegion cms_span(lb, ub);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5580
      _modUnionTable.dirty_range_iterate_clear(cms_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5581
                                               &markFromDirtyCardsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5582
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5583
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5584
        gclog_or_tty->print(" (re-scanned "SIZE_FORMAT" dirty cards in cms gen) ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5585
          markFromDirtyCardsClosure.num_dirty_cards());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5586
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5587
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5588
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5589
      // .. and then repeat for dirty cards in perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5590
      markFromDirtyCardsClosure.set_space(_permGen->cmsSpace());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5591
      MemRegion ur = _permGen->used_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5592
      HeapWord* lb = ur.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5593
      HeapWord* ub = (HeapWord*)round_to((intptr_t)ur.end(), alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5594
      MemRegion perm_span(lb, ub);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5595
      _modUnionTable.dirty_range_iterate_clear(perm_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5596
                                               &markFromDirtyCardsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5597
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5598
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5599
        gclog_or_tty->print(" (re-scanned "SIZE_FORMAT" dirty cards in perm gen) ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5600
          markFromDirtyCardsClosure.num_dirty_cards());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5601
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5602
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5603
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5604
  if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5605
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5606
    HandleMark hm;  // Discard invalid handles created during verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5607
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5608
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5609
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5610
    TraceTime t("root rescan", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5611
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5612
    verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5613
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5614
    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
  5615
    GenCollectedHeap::StrongRootsScope srs(gch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5616
    gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5617
                                  true,  // younger gens as roots
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5618
                                  false, // use the local StrongRootsScope
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5619
                                  true,  // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5620
                                  SharedHeap::ScanningOption(roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5621
                                  &mrias_cl,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5622
                                  true,   // walk code active on stacks
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5623
                                  NULL);
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5624
    assert(should_unload_classes()
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5625
           || (roots_scanning_options() & SharedHeap::SO_CodeCache),
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5626
           "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
  5627
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5628
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5629
  // Restore evacuated mark words, if any, used for overflow list links
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5630
  if (!CMSOverflowEarlyRestoration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5631
    restore_preserved_marks_if_any();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5632
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5633
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5634
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5635
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5636
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5637
// Parallel Reference Processing Task Proxy Class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5638
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5639
class CMSRefProcTaskProxy: public AbstractGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5640
  typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5641
  CMSCollector*          _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5642
  CMSBitMap*             _mark_bit_map;
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5643
  const MemRegion        _span;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5644
  OopTaskQueueSet*       _task_queues;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5645
  ParallelTaskTerminator _term;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5646
  ProcessTask&           _task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5647
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5648
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5649
  CMSRefProcTaskProxy(ProcessTask&     task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5650
                      CMSCollector*    collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5651
                      const MemRegion& span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5652
                      CMSBitMap*       mark_bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5653
                      int              total_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5654
                      OopTaskQueueSet* task_queues):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5655
    AbstractGangTask("Process referents by policy in parallel"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5656
    _task(task),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5657
    _collector(collector), _span(span), _mark_bit_map(mark_bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5658
    _task_queues(task_queues),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5659
    _term(total_workers, task_queues)
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5660
    {
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5661
      assert(_collector->_span.equals(_span) && !_span.is_empty(),
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5662
             "Inconsistency in _span");
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5663
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5664
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5665
  OopTaskQueueSet* task_queues() { return _task_queues; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5666
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5667
  OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5668
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5669
  ParallelTaskTerminator* terminator() { return &_term; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5670
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5671
  void do_work_steal(int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5672
                     CMSParDrainMarkingStackClosure* drain,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5673
                     CMSParKeepAliveClosure* keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5674
                     int* seed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5675
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5676
  virtual void work(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5677
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5678
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5679
void CMSRefProcTaskProxy::work(int i) {
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5680
  assert(_collector->_span.equals(_span), "Inconsistency in _span");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5681
  CMSParKeepAliveClosure par_keep_alive(_collector, _span,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5682
                                        _mark_bit_map,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5683
                                        &_collector->_revisitStack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5684
                                        work_queue(i));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5685
  CMSParDrainMarkingStackClosure par_drain_stack(_collector, _span,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5686
                                                 _mark_bit_map,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5687
                                                 &_collector->_revisitStack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5688
                                                 work_queue(i));
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5689
  CMSIsAliveClosure is_alive_closure(_span, _mark_bit_map);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5690
  _task.work(i, is_alive_closure, par_keep_alive, par_drain_stack);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5691
  if (_task.marks_oops_alive()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5692
    do_work_steal(i, &par_drain_stack, &par_keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5693
                  _collector->hash_seed(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5694
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5695
  assert(work_queue(i)->size() == 0, "work_queue should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5696
  assert(_collector->_overflow_list == NULL, "non-empty _overflow_list");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5697
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5698
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5699
class CMSRefEnqueueTaskProxy: public AbstractGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5700
  typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5701
  EnqueueTask& _task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5702
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5703
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5704
  CMSRefEnqueueTaskProxy(EnqueueTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5705
    : AbstractGangTask("Enqueue reference objects in parallel"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5706
      _task(task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5707
  { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5708
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5709
  virtual void work(int i)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5710
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5711
    _task.work(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5712
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5713
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5714
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5715
CMSParKeepAliveClosure::CMSParKeepAliveClosure(CMSCollector* collector,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5716
  MemRegion span, CMSBitMap* bit_map, CMSMarkStack* revisit_stack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5717
  OopTaskQueue* work_queue):
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5718
   Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5719
   _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5720
   _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5721
   _work_queue(work_queue),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5722
   _mark_and_push(collector, span, bit_map, revisit_stack, work_queue),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5723
   _low_water_mark(MIN2((uint)(work_queue->max_elems()/4),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5724
                        (uint)(CMSWorkQueueDrainThreshold * ParallelGCThreads)))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5725
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5726
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5727
// . see if we can share work_queues with ParNew? XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5728
void CMSRefProcTaskProxy::do_work_steal(int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5729
  CMSParDrainMarkingStackClosure* drain,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5730
  CMSParKeepAliveClosure* keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5731
  int* seed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5732
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5733
  NOT_PRODUCT(int num_steals = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5734
  oop obj_to_scan;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5735
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5736
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5737
    // Completely finish any left over work from (an) earlier round(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5738
    drain->trim_queue(0);
2346
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  5739
    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
  5740
                                         (size_t)ParGCDesiredObjsFromOverflowList);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5741
    // Now check if there's any work in the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5742
    if (_collector->par_take_from_overflow_list(num_from_overflow_list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5743
                                                work_q)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5744
      // Found something in global overflow list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5745
      // not yet ready to go stealing work from others.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5746
      // We'd like to assert(work_q->size() != 0, ...)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5747
      // because we just took work from the overflow list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5748
      // but of course we can't, since all of that might have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5749
      // been already stolen from us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5750
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5751
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5752
    // Verify that we have no work before we resort to stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5753
    assert(work_q->size() == 0, "Have work, shouldn't steal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5754
    // Try to steal from other queues that have work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5755
    if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5756
      NOT_PRODUCT(num_steals++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5757
      assert(obj_to_scan->is_oop(), "Oops, not an oop!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5758
      assert(_mark_bit_map->isMarked((HeapWord*)obj_to_scan), "Stole an unmarked oop?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5759
      // Do scanning work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5760
      obj_to_scan->oop_iterate(keep_alive);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5761
      // Loop around, finish this work, and try to steal some more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5762
    } else if (terminator()->offer_termination()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5763
      break;  // nirvana from the infinite cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5764
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5765
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5766
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5767
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5768
      gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5769
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5770
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5771
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5772
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5773
void CMSRefProcTaskExecutor::execute(ProcessTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5774
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5775
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5776
  WorkGang* workers = gch->workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5777
  assert(workers != NULL, "Need parallel worker threads.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5778
  int n_workers = workers->total_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5779
  CMSRefProcTaskProxy rp_task(task, &_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5780
                              _collector.ref_processor()->span(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5781
                              _collector.markBitMap(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5782
                              n_workers, _collector.task_queues());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5783
  workers->run_task(&rp_task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5784
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5785
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5786
void CMSRefProcTaskExecutor::execute(EnqueueTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5787
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5788
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5789
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5790
  WorkGang* workers = gch->workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5791
  assert(workers != NULL, "Need parallel worker threads.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5792
  CMSRefEnqueueTaskProxy enq_task(task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5793
  workers->run_task(&enq_task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5794
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5795
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5796
void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5797
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5798
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5799
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5800
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5801
  ReferenceProcessor* rp = ref_processor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5802
  assert(rp->span().equals(_span), "Spans should be equal");
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5803
  assert(!rp->enqueuing_is_done(), "Enqueuing should not be complete");
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5804
  // Process weak references.
1610
5dddd195cc86 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 1606
diff changeset
  5805
  rp->setup_policy(clear_all_soft_refs);
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5806
  verify_work_stacks_empty();
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5807
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5808
  CMSKeepAliveClosure cmsKeepAliveClosure(this, _span, &_markBitMap,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5809
                                          &_markStack, &_revisitStack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5810
                                          false /* !preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5811
  CMSDrainMarkingStackClosure cmsDrainMarkingStackClosure(this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5812
                                _span, &_markBitMap, &_markStack,
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  5813
                                &cmsKeepAliveClosure, false /* !preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5814
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5815
    TraceTime t("weak refs processing", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5816
    if (rp->processing_is_mt()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5817
      CMSRefProcTaskExecutor task_executor(*this);
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5818
      rp->process_discovered_references(&_is_alive_closure,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5819
                                        &cmsKeepAliveClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5820
                                        &cmsDrainMarkingStackClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5821
                                        &task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5822
    } else {
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5823
      rp->process_discovered_references(&_is_alive_closure,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5824
                                        &cmsKeepAliveClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5825
                                        &cmsDrainMarkingStackClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5826
                                        NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5827
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5828
    verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5829
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5830
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  5831
  if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5832
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5833
      TraceTime t("class unloading", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5834
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5835
      // Follow SystemDictionary roots and unload classes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5836
      bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5837
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5838
      // Follow CodeCache roots and unload any methods marked for unloading
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5839
      CodeCache::do_unloading(&_is_alive_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5840
                              &cmsKeepAliveClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5841
                              purged_class);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5842
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5843
      cmsDrainMarkingStackClosure.do_void();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5844
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5845
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5846
      // Update subklass/sibling/implementor links in KlassKlass descendants
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5847
      assert(!_revisitStack.isEmpty(), "revisit stack should not be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5848
      oop k;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5849
      while ((k = _revisitStack.pop()) != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5850
        ((Klass*)(oopDesc*)k)->follow_weak_klass_links(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5851
                       &_is_alive_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5852
                       &cmsKeepAliveClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5853
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5854
      assert(!ClassUnloading ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5855
             (_markStack.isEmpty() && overflow_list_is_empty()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5856
             "Should not have found new reachable objects");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5857
      assert(_revisitStack.isEmpty(), "revisit stack should have been drained");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5858
      cmsDrainMarkingStackClosure.do_void();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5859
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5860
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5861
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5862
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5863
      TraceTime t("scrub symbol & string tables", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5864
      // Now clean up stale oops in SymbolTable and StringTable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5865
      SymbolTable::unlink(&_is_alive_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5866
      StringTable::unlink(&_is_alive_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5867
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5868
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5869
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5870
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5871
  // Restore any preserved marks as a result of mark stack or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5872
  // work queue overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5873
  restore_preserved_marks_if_any();  // done single-threaded for now
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5874
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5875
  rp->set_enqueuing_is_done(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5876
  if (rp->processing_is_mt()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5877
    CMSRefProcTaskExecutor task_executor(*this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5878
    rp->enqueue_discovered_references(&task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5879
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5880
    rp->enqueue_discovered_references(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5881
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5882
  rp->verify_no_references_recorded();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5883
  assert(!rp->discovery_enabled(), "should have been disabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5884
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5885
  // JVMTI object tagging is based on JNI weak refs. If any of these
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5886
  // refs were cleared then JVMTI needs to update its maps and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5887
  // maybe post ObjectFrees to agents.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5888
  JvmtiExport::cms_ref_processing_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5889
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5890
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5891
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5892
void CMSCollector::check_correct_thread_executing() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5893
  Thread* t = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5894
  // Only the VM thread or the CMS thread should be here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5895
  assert(t->is_ConcurrentGC_thread() || t->is_VM_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5896
         "Unexpected thread type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5897
  // If this is the vm thread, the foreground process
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5898
  // should not be waiting.  Note that _foregroundGCIsActive is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5899
  // true while the foreground collector is waiting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5900
  if (_foregroundGCShouldWait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5901
    // We cannot be the VM thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5902
    assert(t->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5903
           "Should be CMS thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5904
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5905
    // We can be the CMS thread only if we are in a stop-world
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5906
    // phase of CMS collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5907
    if (t->is_ConcurrentGC_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5908
      assert(_collectorState == InitialMarking ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5909
             _collectorState == FinalMarking,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5910
             "Should be a stop-world phase");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5911
      // The CMS thread should be holding the CMS_token.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5912
      assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5913
             "Potential interference with concurrently "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5914
             "executing VM thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5915
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5916
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5917
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5918
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5919
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5920
void CMSCollector::sweep(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5921
  assert(_collectorState == Sweeping, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5922
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5923
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5924
  verify_overflow_empty();
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5925
  increment_sweep_count();
6245
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  5926
  TraceCMSMemoryManagerStats tms(_collectorState);
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  5927
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5928
  _inter_sweep_timer.stop();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5929
  _inter_sweep_estimate.sample(_inter_sweep_timer.seconds());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5930
  size_policy()->avg_cms_free_at_sweep()->sample(_cmsGen->free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5931
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5932
  // PermGen verification support: If perm gen sweeping is disabled in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5933
  // this cycle, we preserve the perm gen object "deadness" information
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5934
  // in the perm_gen_verify_bit_map. In order to do that we traverse
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5935
  // 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
  5936
  if (verifying() && !should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5937
    assert(perm_gen_verify_bit_map()->sizeInBits() != 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5938
           "Should have already been allocated");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5939
    MarkDeadObjectsClosure mdo(this, _permGen->cmsSpace(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5940
                               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
  5941
    if (asynch) {
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5942
      CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(),
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5943
                               bitMapLock());
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5944
      _permGen->cmsSpace()->blk_iterate(&mdo);
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5945
    } else {
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5946
      // 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
  5947
      // the requisite locks/tokens.
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5948
      _permGen->cmsSpace()->blk_iterate(&mdo);
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5949
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5950
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5951
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5952
  assert(!_intra_sweep_timer.is_active(), "Should not be active");
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5953
  _intra_sweep_timer.reset();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5954
  _intra_sweep_timer.start();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5955
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5956
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5957
    CMSPhaseAccounting pa(this, "sweep", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5958
    // First sweep the old gen then the perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5959
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5960
      CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5961
                               bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5962
      sweepWork(_cmsGen, asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5963
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5964
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5965
    // Now repeat for perm gen
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  5966
    if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5967
      CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5968
                             bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5969
      sweepWork(_permGen, asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5970
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5971
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5972
    // Update Universe::_heap_*_at_gc figures.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5973
    // We need all the free list locks to make the abstract state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5974
    // transition from Sweeping to Resetting. See detailed note
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5975
    // further below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5976
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5977
      CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5978
                               _permGen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5979
      // Update heap occupancy information which is used as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5980
      // input to soft ref clearing policy at the next gc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5981
      Universe::update_heap_info_at_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5982
      _collectorState = Resizing;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5983
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5984
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5985
    // already have needed locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5986
    sweepWork(_cmsGen,  asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5987
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  5988
    if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5989
      sweepWork(_permGen, asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5990
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5991
    // Update heap occupancy information which is used as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5992
    // input to soft ref clearing policy at the next gc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5993
    Universe::update_heap_info_at_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5994
    _collectorState = Resizing;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5995
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5996
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5997
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5998
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5999
  _intra_sweep_timer.stop();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6000
  _intra_sweep_estimate.sample(_intra_sweep_timer.seconds());
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6001
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6002
  _inter_sweep_timer.reset();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6003
  _inter_sweep_timer.start();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6004
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6005
  update_time_of_last_gc(os::javaTimeMillis());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6006
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6007
  // NOTE on abstract state transitions:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6008
  // Mutators allocate-live and/or mark the mod-union table dirty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6009
  // based on the state of the collection.  The former is done in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6010
  // the interval [Marking, Sweeping] and the latter in the interval
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6011
  // [Marking, Sweeping).  Thus the transitions into the Marking state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6012
  // and out of the Sweeping state must be synchronously visible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6013
  // globally to the mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6014
  // The transition into the Marking state happens with the world
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6015
  // stopped so the mutators will globally see it.  Sweeping is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6016
  // done asynchronously by the background collector so the transition
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6017
  // from the Sweeping state to the Resizing state must be done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6018
  // under the freelistLock (as is the check for whether to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6019
  // allocate-live and whether to dirty the mod-union table).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6020
  assert(_collectorState == Resizing, "Change of collector state to"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6021
    " Resizing must be done under the freelistLocks (plural)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6022
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6023
  // Now that sweeping has been completed, if the GCH's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6024
  // incremental_collection_will_fail flag is set, clear it,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6025
  // thus inviting a younger gen collection to promote into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6026
  // this generation. If such a promotion may still fail,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6027
  // the flag will be set again when a young collection is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6028
  // attempted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6029
  // I think the incremental_collection_will_fail flag's use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6030
  // is specific to a 2 generation collection policy, so i'll
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6031
  // assert that that's the configuration we are operating within.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6032
  // The use of the flag can and should be generalized appropriately
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6033
  // in the future to deal with a general n-generation system.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6034
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6035
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6036
  assert(gch->collector_policy()->is_two_generation_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6037
         "Resetting of incremental_collection_will_fail flag"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6038
         " may be incorrect otherwise");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6039
  gch->clear_incremental_collection_will_fail();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6040
  gch->update_full_collections_completed(_collection_count_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6041
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6042
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6043
// FIX ME!!! Looks like this belongs in CFLSpace, with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6044
// CMSGen merely delegating to it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6045
void ConcurrentMarkSweepGeneration::setNearLargestChunk() {
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6046
  double nearLargestPercent = FLSLargestBlockCoalesceProximity;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6047
  HeapWord*  minAddr        = _cmsSpace->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6048
  HeapWord*  largestAddr    =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6049
    (HeapWord*) _cmsSpace->dictionary()->findLargestDict();
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6050
  if (largestAddr == NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6051
    // The dictionary appears to be empty.  In this case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6052
    // try to coalesce at the end of the heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6053
    largestAddr = _cmsSpace->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6054
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6055
  size_t largestOffset     = pointer_delta(largestAddr, minAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6056
  size_t nearLargestOffset =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6057
    (size_t)((double)largestOffset * nearLargestPercent) - MinChunkSize;
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6058
  if (PrintFLSStatistics != 0) {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6059
    gclog_or_tty->print_cr(
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6060
      "CMS: Large Block: " PTR_FORMAT ";"
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6061
      " Proximity: " PTR_FORMAT " -> " PTR_FORMAT,
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6062
      largestAddr,
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6063
      _cmsSpace->nearLargestChunk(), minAddr + nearLargestOffset);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6064
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6065
  _cmsSpace->set_nearLargestChunk(minAddr + nearLargestOffset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6066
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6067
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6068
bool ConcurrentMarkSweepGeneration::isNearLargestChunk(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6069
  return addr >= _cmsSpace->nearLargestChunk();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6070
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6071
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6072
FreeChunk* ConcurrentMarkSweepGeneration::find_chunk_at_end() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6073
  return _cmsSpace->find_chunk_at_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6074
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6075
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6076
void ConcurrentMarkSweepGeneration::update_gc_stats(int current_level,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6077
                                                    bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6078
  // The next lower level has been collected.  Gather any statistics
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6079
  // that are of interest at this point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6080
  if (!full && (current_level + 1) == level()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6081
    // Gather statistics on the young generation collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6082
    collector()->stats().record_gc0_end(used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6083
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6084
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6085
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6086
CMSAdaptiveSizePolicy* ConcurrentMarkSweepGeneration::size_policy() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6087
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6088
  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6089
    "Wrong type of heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6090
  CMSAdaptiveSizePolicy* sp = (CMSAdaptiveSizePolicy*)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6091
    gch->gen_policy()->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6092
  assert(sp->is_gc_cms_adaptive_size_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6093
    "Wrong type of size policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6094
  return sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6095
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6097
void ConcurrentMarkSweepGeneration::rotate_debug_collection_type() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6098
  if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6099
    gclog_or_tty->print("Rotate from %d ", _debug_collection_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6100
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6101
  _debug_collection_type = (CollectionTypes) (_debug_collection_type + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6102
  _debug_collection_type =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6103
    (CollectionTypes) (_debug_collection_type % Unknown_collection_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6104
  if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6105
    gclog_or_tty->print_cr("to %d ", _debug_collection_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6106
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6107
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6108
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6109
void CMSCollector::sweepWork(ConcurrentMarkSweepGeneration* gen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6110
  bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6111
  // We iterate over the space(s) underlying this generation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6112
  // checking the mark bit map to see if the bits corresponding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6113
  // to specific blocks are marked or not. Blocks that are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6114
  // marked are live and are not swept up. All remaining blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6115
  // are swept up, with coalescing on-the-fly as we sweep up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6116
  // contiguous free and/or garbage blocks:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6117
  // We need to ensure that the sweeper synchronizes with allocators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6118
  // and stop-the-world collectors. In particular, the following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6119
  // locks are used:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6120
  // . CMS token: if this is held, a stop the world collection cannot occur
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6121
  // . freelistLock: if this is held no allocation can occur from this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6122
  //                 generation by another thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6123
  // . bitMapLock: if this is held, no other thread can access or update
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6124
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6125
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6126
  // Note that we need to hold the freelistLock if we use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6127
  // block iterate below; else the iterator might go awry if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6128
  // a mutator (or promotion) causes block contents to change
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6129
  // (for instance if the allocator divvies up a block).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6130
  // If we hold the free list lock, for all practical purposes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6131
  // young generation GC's can't occur (they'll usually need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6132
  // promote), so we might as well prevent all young generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6133
  // GC's while we do a sweeping step. For the same reason, we might
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6134
  // as well take the bit map lock for the entire duration
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6135
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6136
  // check that we hold the requisite locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6137
  assert(have_cms_token(), "Should hold cms token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6138
  assert(   (asynch && ConcurrentMarkSweepThread::cms_thread_has_cms_token())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6139
         || (!asynch && ConcurrentMarkSweepThread::vm_thread_has_cms_token()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6140
        "Should possess CMS token to sweep");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6141
  assert_lock_strong(gen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6142
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6143
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6144
  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
  6145
  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
  6146
  gen->cmsSpace()->beginSweepFLCensus((float)(_inter_sweep_timer.seconds()),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6147
                                      _inter_sweep_estimate.padded_average(),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6148
                                      _intra_sweep_estimate.padded_average());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6149
  gen->setNearLargestChunk();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6150
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6151
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6152
    SweepClosure sweepClosure(this, gen, &_markBitMap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6153
                            CMSYield && asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6154
    gen->cmsSpace()->blk_iterate_careful(&sweepClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6155
    // We need to free-up/coalesce garbage/blocks from a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6156
    // co-terminal free run. This is done in the SweepClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6157
    // destructor; so, do not remove this scope, else the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6158
    // end-of-sweep-census below will be off by a little bit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6159
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6160
  gen->cmsSpace()->sweep_completed();
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6161
  gen->cmsSpace()->endSweepFLCensus(sweep_count());
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6162
  if (should_unload_classes()) {                // unloaded classes this cycle,
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6163
    _concurrent_cycles_since_last_unload = 0;   // ... reset count
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6164
  } else {                                      // did not unload classes,
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6165
    _concurrent_cycles_since_last_unload++;     // ... increment count
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6166
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6167
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6168
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6169
// Reset CMS data structures (for now just the marking bit map)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6170
// preparatory for the next cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6171
void CMSCollector::reset(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6172
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6173
  CMSAdaptiveSizePolicy* sp = size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6174
  AdaptiveSizePolicyOutput(sp, gch->total_collections());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6175
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6176
    CMSTokenSyncWithLocks ts(true, bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6177
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6178
    // If the state is not "Resetting", the foreground  thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6179
    // has done a collection and the resetting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6180
    if (_collectorState != Resetting) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6181
      assert(_collectorState == Idling, "The state should only change"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6182
        " because the foreground collector has finished the collection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6183
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6184
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6185
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6186
    // Clear the mark bitmap (no grey objects to start with)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6187
    // for the next cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6188
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6189
    CMSPhaseAccounting cmspa(this, "reset", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6190
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6191
    HeapWord* curAddr = _markBitMap.startWord();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6192
    while (curAddr < _markBitMap.endWord()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6193
      size_t remaining  = pointer_delta(_markBitMap.endWord(), curAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6194
      MemRegion chunk(curAddr, MIN2(CMSBitMapYieldQuantum, remaining));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6195
      _markBitMap.clear_large_range(chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6196
      if (ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6197
          !foregroundGCIsActive() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6198
          CMSYield) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6199
        assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6200
               "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6201
        assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6202
        bitMapLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6203
        ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6204
        ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6205
        stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6206
        if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6207
          incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6208
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6209
        icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6210
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6211
        // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6212
        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
  6213
                         ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6214
                         !CMSCollector::foregroundGCIsActive(); ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6215
          os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6216
          ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6217
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6218
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6219
        ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6220
        bitMapLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6221
        startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6222
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6223
      curAddr = chunk.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6224
    }
5343
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  6225
    // 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
  6226
    // 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
  6227
    // 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
  6228
    // and count.
95a5c4b89273 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 5040
diff changeset
  6229
    sp->reset_gc_overhead_limit_count();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6230
    _collectorState = Idling;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6231
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6232
    // already have the lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6233
    assert(_collectorState == Resetting, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6234
    assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6235
    _markBitMap.clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6236
    _collectorState = Idling;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6237
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6238
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6239
  // Stop incremental mode after a cycle completes, so that any future cycles
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6240
  // are triggered by allocation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6241
  stop_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6242
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6243
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6244
    if (RotateCMSCollectionTypes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6245
      _cmsGen->rotate_debug_collection_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6246
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6247
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6248
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6249
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6250
void CMSCollector::do_CMS_operation(CMS_op_type op) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6251
  gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6252
  TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6253
  TraceTime t("GC", PrintGC, !PrintGCDetails, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6254
  TraceCollectorStats tcs(counters());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6255
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6256
  switch (op) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6257
    case CMS_op_checkpointRootsInitial: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6258
      checkpointRootsInitial(true);       // asynch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6259
      if (PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6260
        _cmsGen->printOccupancy("initial-mark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6261
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6262
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6263
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6264
    case CMS_op_checkpointRootsFinal: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6265
      checkpointRootsFinal(true,    // asynch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6266
                           false,   // !clear_all_soft_refs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6267
                           false);  // !init_mark_was_synchronous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6268
      if (PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6269
        _cmsGen->printOccupancy("remark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6270
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6271
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6272
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6273
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6274
      fatal("No such CMS_op");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6275
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6276
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6277
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6278
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6279
size_t const CMSCollector::skip_header_HeapWords() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6280
  return FreeChunk::header_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6281
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6283
// Try and collect here conditions that should hold when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6284
// CMS thread is exiting. The idea is that the foreground GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6285
// thread should not be blocked if it wants to terminate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6286
// the CMS thread and yet continue to run the VM for a while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6287
// after that.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6288
void CMSCollector::verify_ok_to_terminate() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6289
  assert(Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6290
         "should be called by CMS thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6291
  assert(!_foregroundGCShouldWait, "should be false");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6292
  // We could check here that all the various low-level locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6293
  // are not held by the CMS thread, but that is overkill; see
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6294
  // also CMSThread::verify_ok_to_terminate() where the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6295
  // is checked.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6296
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6297
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6298
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6299
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
  6300
   assert(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1),
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  6301
          "missing Printezis mark?");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6302
  HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6303
  size_t size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6304
  assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6305
         "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6306
  assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6307
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6308
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6309
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6310
// A variant of the above (block_size_using_printezis_bits()) except
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6311
// that we return 0 if the P-bits are not yet set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6312
size_t CMSCollector::block_size_if_printezis_bits(HeapWord* addr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6313
  if (_markBitMap.isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6314
    assert(_markBitMap.isMarked(addr + 1), "Missing Printezis bit?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6315
    HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6316
    size_t size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6317
    assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6318
           "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6319
    assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6320
    return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6321
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6322
    assert(!_markBitMap.isMarked(addr + 1), "Bit map inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6323
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6324
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6325
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6326
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6327
HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6328
  size_t sz = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6329
  oop p = (oop)addr;
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6330
  if (p->klass_or_null() != NULL && p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6331
    sz = CompactibleFreeListSpace::adjustObjectSize(p->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6332
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6333
    sz = block_size_using_printezis_bits(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6334
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6335
  assert(sz > 0, "size must be nonzero");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6336
  HeapWord* next_block = addr + sz;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6337
  HeapWord* next_card  = (HeapWord*)round_to((uintptr_t)next_block,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6338
                                             CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6339
  assert(round_down((uintptr_t)addr,      CardTableModRefBS::card_size) <
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6340
         round_down((uintptr_t)next_card, CardTableModRefBS::card_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6341
         "must be different cards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6342
  return next_card;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6343
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6344
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6345
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6346
// CMS Bit Map Wrapper /////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6347
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6348
// Construct a CMS bit map infrastructure, but don't create the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6349
// bit vector itself. That is done by a separate call CMSBitMap::allocate()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6350
// further below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6351
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
  6352
  _bm(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6353
  _shifter(shifter),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6354
  _lock(mutex_rank >= 0 ? new Mutex(mutex_rank, mutex_name, true) : NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6355
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6356
  _bmStartWord = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6357
  _bmWordSize  = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6358
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6359
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6360
bool CMSBitMap::allocate(MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6361
  _bmStartWord = mr.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6362
  _bmWordSize  = mr.word_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6363
  ReservedSpace brs(ReservedSpace::allocation_align_size_up(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6364
                     (_bmWordSize >> (_shifter + LogBitsPerByte)) + 1));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6365
  if (!brs.is_reserved()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6366
    warning("CMS bit map allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6367
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6368
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6369
  // For now we'll just commit all of the bit map up fromt.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6370
  // Later on we'll try to be more parsimonious with swap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6371
  if (!_virtual_space.initialize(brs, brs.size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6372
    warning("CMS bit map backing store failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6373
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6374
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6375
  assert(_virtual_space.committed_size() == brs.size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6376
         "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
  6377
  _bm.set_map((BitMap::bm_word_t*)_virtual_space.low());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6378
  assert(_virtual_space.committed_size() << (_shifter + LogBitsPerByte) >=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6379
         _bmWordSize, "inconsistency in bit map sizing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6380
  _bm.set_size(_bmWordSize >> _shifter);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6381
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6382
  // bm.clear(); // can we rely on getting zero'd memory? verify below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6383
  assert(isAllClear(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6384
         "Expected zero'd memory from ReservedSpace constructor");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6385
  assert(_bm.size() == heapWordDiffToOffsetDiff(sizeInWords()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6386
         "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6387
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6388
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6389
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6390
void CMSBitMap::dirty_range_iterate_clear(MemRegion mr, MemRegionClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6391
  HeapWord *next_addr, *end_addr, *last_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6392
  assert_locked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6393
  assert(covers(mr), "out-of-range error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6394
  // XXX assert that start and end are appropriately aligned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6395
  for (next_addr = mr.start(), end_addr = mr.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6396
       next_addr < end_addr; next_addr = last_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6397
    MemRegion dirty_region = getAndClearMarkedRegion(next_addr, end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6398
    last_addr = dirty_region.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6399
    if (!dirty_region.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6400
      cl->do_MemRegion(dirty_region);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6401
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6402
      assert(last_addr == end_addr, "program logic");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6403
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6404
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6405
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6406
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6407
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6408
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6409
void CMSBitMap::assert_locked() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6410
  CMSLockVerifier::assert_locked(lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6411
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6412
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6413
bool CMSBitMap::covers(MemRegion mr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6414
  // assert(_bm.map() == _virtual_space.low(), "map inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6415
  assert((size_t)_bm.size() == (_bmWordSize >> _shifter),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6416
         "size inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6417
  return (mr.start() >= _bmStartWord) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6418
         (mr.end()   <= endWord());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6419
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6420
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6421
bool CMSBitMap::covers(HeapWord* start, size_t size) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6422
    return (start >= _bmStartWord && (start + size) <= endWord());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6423
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6424
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6425
void CMSBitMap::verifyNoOneBitsInRange(HeapWord* left, HeapWord* right) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6426
  // verify that there are no 1 bits in the interval [left, right)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6427
  FalseBitMapClosure falseBitMapClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6428
  iterate(&falseBitMapClosure, left, right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6429
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6430
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6431
void CMSBitMap::region_invariant(MemRegion mr)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6432
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6433
  assert_locked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6434
  // mr = mr.intersection(MemRegion(_bmStartWord, _bmWordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6435
  assert(!mr.is_empty(), "unexpected empty region");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6436
  assert(covers(mr), "mr should be covered by bit map");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6437
  // convert address range into offset range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6438
  size_t start_ofs = heapWordToOffset(mr.start());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6439
  // Make sure that end() is appropriately aligned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6440
  assert(mr.end() == (HeapWord*)round_to((intptr_t)mr.end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6441
                        (1 << (_shifter+LogHeapWordSize))),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6442
         "Misaligned mr.end()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6443
  size_t end_ofs   = heapWordToOffset(mr.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6444
  assert(end_ofs > start_ofs, "Should mark at least one bit");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6445
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6446
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6447
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6448
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6449
bool CMSMarkStack::allocate(size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6450
  // allocate a stack of the requisite depth
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6451
  ReservedSpace rs(ReservedSpace::allocation_align_size_up(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6452
                   size * sizeof(oop)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6453
  if (!rs.is_reserved()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6454
    warning("CMSMarkStack allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6455
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6456
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6457
  if (!_virtual_space.initialize(rs, rs.size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6458
    warning("CMSMarkStack backing store failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6459
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6460
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6461
  assert(_virtual_space.committed_size() == rs.size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6462
         "didn't reserve backing store for all of CMS stack?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6463
  _base = (oop*)(_virtual_space.low());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6464
  _index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6465
  _capacity = size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6466
  NOT_PRODUCT(_max_depth = 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6467
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6468
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6469
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6470
// XXX FIX ME !!! In the MT case we come in here holding a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6471
// leaf lock. For printing we need to take a further lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6472
// which has lower rank. We need to recallibrate the two
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6473
// lock-ranks involved in order to be able to rpint the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6474
// messages below. (Or defer the printing to the caller.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6475
// For now we take the expedient path of just disabling the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6476
// messages for the problematic case.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6477
void CMSMarkStack::expand() {
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
  6478
  assert(_capacity <= MarkStackSizeMax, "stack bigger than permitted");
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
  6479
  if (_capacity == MarkStackSizeMax) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6480
    if (_hit_limit++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6481
      // We print a warning message only once per CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6482
      gclog_or_tty->print_cr(" (benign) Hit CMSMarkStack max size limit");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6483
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6484
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6485
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6486
  // Double capacity if possible
5035
0e498c4df637 6928081: G1: rename parameters common with CMS
jmasa
parents: 4738
diff changeset
  6487
  size_t new_capacity = MIN2(_capacity*2, MarkStackSizeMax);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6488
  // Do not give up existing stack until we have managed to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6489
  // get the double capacity that we desired.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6490
  ReservedSpace rs(ReservedSpace::allocation_align_size_up(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6491
                   new_capacity * sizeof(oop)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6492
  if (rs.is_reserved()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6493
    // Release the backing store associated with old stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6494
    _virtual_space.release();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6495
    // Reinitialize virtual space for new stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6496
    if (!_virtual_space.initialize(rs, rs.size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6497
      fatal("Not enough swap for expanded marking stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6498
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6499
    _base = (oop*)(_virtual_space.low());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6500
    _index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6501
    _capacity = new_capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6502
  } else if (_failed_double++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6503
    // Failed to double capacity, continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6504
    // we print a detail message only once per CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6505
    gclog_or_tty->print(" (benign) Failed to expand marking stack from "SIZE_FORMAT"K to "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6506
            SIZE_FORMAT"K",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6507
            _capacity / K, new_capacity / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6508
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6509
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6510
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6511
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6512
// Closures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6513
// XXX: there seems to be a lot of code  duplication here;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6514
// should refactor and consolidate common code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6515
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6516
// This closure is used to mark refs into the CMS generation in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6517
// the CMS bit map. Called at the first checkpoint. This closure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6518
// assumes that we do not need to re-mark dirty cards; if the CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6519
// generation on which this is used is not an oldest (modulo perm gen)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6520
// generation then this will lose younger_gen cards!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6521
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6522
MarkRefsIntoClosure::MarkRefsIntoClosure(
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6523
  MemRegion span, CMSBitMap* bitMap):
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6524
    _span(span),
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6525
    _bitMap(bitMap)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6526
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6527
    assert(_ref_processor == NULL, "deliberately left NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6528
    assert(_bitMap->covers(_span), "_bitMap/_span mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6529
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6530
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6531
void MarkRefsIntoClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6532
  // 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
  6533
  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
  6534
  HeapWord* addr = (HeapWord*)obj;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6535
  if (_span.contains(addr)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6536
    // 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
  6537
    _bitMap->mark(addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6538
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6539
}
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6540
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6541
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
  6542
void MarkRefsIntoClosure::do_oop(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6543
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6544
// A variant of the above, used for CMS marking verification.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6545
MarkRefsIntoVerifyClosure::MarkRefsIntoVerifyClosure(
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6546
  MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm):
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6547
    _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6548
    _verification_bm(verification_bm),
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6549
    _cms_bm(cms_bm)
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6550
{
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6551
    assert(_ref_processor == NULL, "deliberately left NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6552
    assert(_verification_bm->covers(_span), "_verification_bm/_span mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6553
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6554
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6555
void MarkRefsIntoVerifyClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6556
  // 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
  6557
  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
  6558
  HeapWord* addr = (HeapWord*)obj;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6559
  if (_span.contains(addr)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6560
    _verification_bm->mark(addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6561
    if (!_cms_bm->isMarked(addr)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6562
      oop(addr)->print();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6563
      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
  6564
      fatal("... aborting");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6565
    }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6566
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6567
}
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6568
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6569
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
  6570
void MarkRefsIntoVerifyClosure::do_oop(narrowOop* p) { MarkRefsIntoVerifyClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6571
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6572
//////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6573
// MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6574
//////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6575
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6576
MarkRefsIntoAndScanClosure::MarkRefsIntoAndScanClosure(MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6577
                                                       ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6578
                                                       CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6579
                                                       CMSBitMap* mod_union_table,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6580
                                                       CMSMarkStack*  mark_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6581
                                                       CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6582
                                                       CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6583
                                                       bool should_yield,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6584
                                                       bool concurrent_precleaning):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6585
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6586
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6587
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6588
  _mark_stack(mark_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6589
  _pushAndMarkClosure(collector, span, rp, bit_map, mod_union_table,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6590
                      mark_stack, revisit_stack, concurrent_precleaning),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6591
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6592
  _concurrent_precleaning(concurrent_precleaning),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6593
  _freelistLock(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6594
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6595
  _ref_processor = rp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6596
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6597
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6598
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6599
// This closure is used to mark refs into the CMS generation at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6600
// second (final) checkpoint, and to scan and transitively follow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6601
// the unmarked oops. It is also used during the concurrent precleaning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6602
// phase while scanning objects on dirty cards in the CMS generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6603
// The marks are made in the marking bit map and the marking stack is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6604
// used for keeping the (newly) grey objects during the scan.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6605
// 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
  6606
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
  6607
  if (obj != NULL) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6608
    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
  6609
    HeapWord* addr = (HeapWord*)obj;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6610
    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
  6611
    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
  6612
           "overflow list should be empty");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6613
    if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6614
        !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6615
      // mark bit map (object is now grey)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6616
      _bit_map->mark(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6617
      // push on marking stack (stack should be empty), and drain the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6618
      // stack by applying this closure to the oops in the oops popped
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6619
      // 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
  6620
      bool res = _mark_stack->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6621
      assert(res, "Should have space to push on empty stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6622
      do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6623
        oop new_oop = _mark_stack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6624
        assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6625
        assert(new_oop->is_parsable(), "Found unparsable oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6626
        assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6627
               "only grey objects on this stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6628
        // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6629
        // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6630
        new_oop->oop_iterate(&_pushAndMarkClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6631
        // check if it's time to yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6632
        do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6633
      } while (!_mark_stack->isEmpty() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6634
               (!_concurrent_precleaning && take_from_overflow_list()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6635
        // if marking stack is empty, and we are not doing this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6636
        // during precleaning, then check the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6637
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6638
    assert(_mark_stack->isEmpty(), "post-condition (eager drainage)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6639
    assert(_collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6640
           "overflow list was drained above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6641
    // We could restore evacuated mark words, if any, used for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6642
    // overflow list links here because the overflow list is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6643
    // provably empty here. That would reduce the maximum
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6644
    // size requirements for preserved_{oop,mark}_stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6645
    // But we'll just postpone it until we are all done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6646
    // so we can just stream through.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6647
    if (!_concurrent_precleaning && CMSOverflowEarlyRestoration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6648
      _collector->restore_preserved_marks_if_any();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6649
      assert(_collector->no_preserved_marks(), "No preserved marks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6650
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6651
    assert(!CMSOverflowEarlyRestoration || _collector->no_preserved_marks(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6652
           "All preserved marks should have been restored above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6653
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6654
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6655
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6656
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
  6657
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
  6658
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6659
void MarkRefsIntoAndScanClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6660
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6661
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6662
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6663
  assert_lock_strong(_bit_map->lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6664
  // relinquish the free_list_lock and bitMaplock()
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  6665
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6666
  _bit_map->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6667
  _freelistLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6668
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6669
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6670
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6671
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6672
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6673
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6674
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6675
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6676
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6677
  // 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
  6678
  for (unsigned i = 0;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6679
       i < CMSYieldSleepCount &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6680
       ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6681
       !CMSCollector::foregroundGCIsActive();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6682
       ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6683
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6684
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6685
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6686
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6687
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6688
  _freelistLock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6689
  _bit_map->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6690
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6691
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6692
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6693
///////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6694
// Par_MarkRefsIntoAndScanClosure: a parallel version of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6695
//                                 MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6696
///////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6697
Par_MarkRefsIntoAndScanClosure::Par_MarkRefsIntoAndScanClosure(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6698
  CMSCollector* collector, MemRegion span, ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6699
  CMSBitMap* bit_map, OopTaskQueue* work_queue, CMSMarkStack*  revisit_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6700
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6701
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6702
  _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6703
  _low_water_mark(MIN2((uint)(work_queue->max_elems()/4),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6704
                       (uint)(CMSWorkQueueDrainThreshold * ParallelGCThreads))),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6705
  _par_pushAndMarkClosure(collector, span, rp, bit_map, work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6706
                          revisit_stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6707
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6708
  _ref_processor = rp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6709
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6710
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6711
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6712
// This closure is used to mark refs into the CMS generation at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6713
// second (final) checkpoint, and to scan and transitively follow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6714
// the unmarked oops. The marks are made in the marking bit map and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6715
// the work_queue is used for keeping the (newly) grey objects during
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6716
// the scan phase whence they are also available for stealing by parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6717
// threads. Since the marking bit map is shared, updates are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6718
// synchronized (via CAS).
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6719
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
  6720
  if (obj != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6721
    // Ignore mark word because this could be an already marked oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6722
    // 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
  6723
    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
  6724
    HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6725
    if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6726
        !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6727
      // mark bit map (object will become grey):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6728
      // It is possible for several threads to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6729
      // trying to "claim" this object concurrently;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6730
      // the unique thread that succeeds in marking the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6731
      // object first will do the subsequent push on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6732
      // to the work queue (or overflow list).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6733
      if (_bit_map->par_mark(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6734
        // push on work_queue (which may not be empty), and trim the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6735
        // queue to an appropriate length by applying this closure to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6736
        // the oops in the oops popped from the stack (i.e. blacken the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6737
        // grey objects)
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6738
        bool res = _work_queue->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6739
        assert(res, "Low water mark should be less than capacity?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6740
        trim_queue(_low_water_mark);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6741
      } // Else, another thread claimed the object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6742
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6743
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6744
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6745
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6746
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
  6747
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
  6748
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6749
// This closure is used to rescan the marked objects on the dirty cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6750
// in the mod union table and the card table proper.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6751
size_t ScanMarkedObjectsAgainCarefullyClosure::do_object_careful_m(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6752
  oop p, MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6753
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6754
  size_t size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6755
  HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6756
  DEBUG_ONLY(_collector->verify_work_stacks_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6757
  assert(_span.contains(addr), "we are scanning the CMS generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6758
  // check if it's time to yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6759
  if (do_yield_check()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6760
    // We yielded for some foreground stop-world work,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6761
    // and we have been asked to abort this ongoing preclean cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6762
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6763
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6764
  if (_bitMap->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6765
    // it's marked; is it potentially uninitialized?
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6766
    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
  6767
      // 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
  6768
      // 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
  6769
      // 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
  6770
      if (CMSPermGenPrecleaningEnabled &&
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  6771
          (!p->is_conc_safe() || !p->is_parsable())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6772
        // Signal precleaning to redirty the card since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6773
        // the klass pointer is already installed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6774
        assert(size == 0, "Initial value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6775
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6776
        assert(p->is_parsable(), "must be parsable.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6777
        // an initialized object; ignore mark word in verification below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6778
        // since we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6779
        assert(p->is_oop(true), "should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6780
        if (p->is_objArray()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6781
          // objArrays are precisely marked; restrict scanning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6782
          // to dirty cards only.
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6783
          size = CompactibleFreeListSpace::adjustObjectSize(
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6784
                   p->oop_iterate(_scanningClosure, mr));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6785
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6786
          // A non-array may have been imprecisely marked; we need
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6787
          // to scan object in its entirety.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6788
          size = CompactibleFreeListSpace::adjustObjectSize(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6789
                   p->oop_iterate(_scanningClosure));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6790
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6791
        #ifdef DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6792
          size_t direct_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6793
            CompactibleFreeListSpace::adjustObjectSize(p->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6794
          assert(size == direct_size, "Inconsistency in size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6795
          assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6796
          if (!_bitMap->isMarked(addr+1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6797
            _bitMap->verifyNoOneBitsInRange(addr+2, addr+size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6798
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6799
            _bitMap->verifyNoOneBitsInRange(addr+2, addr+size-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6800
            assert(_bitMap->isMarked(addr+size-1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6801
                   "inconsistent Printezis mark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6802
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6803
        #endif // DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6804
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6805
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6806
      // an unitialized object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6807
      assert(_bitMap->isMarked(addr+1), "missing Printezis mark?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6808
      HeapWord* nextOneAddr = _bitMap->getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6809
      size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6810
      assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6811
             "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6812
      // Note that pre-cleaning needn't redirty the card. OopDesc::set_klass()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6813
      // will dirty the card when the klass pointer is installed in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6814
      // object (signalling the completion of initialization).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6815
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6816
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6817
    // Either a not yet marked object or an uninitialized object
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6818
    if (p->klass_or_null() == NULL || !p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6819
      // An uninitialized object, skip to the next card, since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6820
      // we may not be able to read its P-bits yet.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6821
      assert(size == 0, "Initial value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6822
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6823
      // An object not (yet) reached by marking: we merely need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6824
      // compute its size so as to go look at the next block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6825
      assert(p->is_oop(true), "should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6826
      size = CompactibleFreeListSpace::adjustObjectSize(p->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6827
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6828
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6829
  DEBUG_ONLY(_collector->verify_work_stacks_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6830
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6831
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6832
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6833
void ScanMarkedObjectsAgainCarefullyClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6834
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6835
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6836
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6837
  assert_lock_strong(_bitMap->lock());
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  6838
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6839
  // relinquish the free_list_lock and bitMaplock()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6840
  _bitMap->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6841
  _freelistLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6842
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6843
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6844
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6845
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6846
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6847
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6848
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6849
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6850
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6851
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6852
  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
  6853
                   ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6854
                   !CMSCollector::foregroundGCIsActive(); ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6855
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6856
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6857
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6858
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6859
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6860
  _freelistLock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6861
  _bitMap->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6862
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6863
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6864
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6865
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6866
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6867
// SurvivorSpacePrecleanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6868
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6869
// This (single-threaded) closure is used to preclean the oops in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6870
// the survivor spaces.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6871
size_t SurvivorSpacePrecleanClosure::do_object_careful(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6872
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6873
  HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6874
  DEBUG_ONLY(_collector->verify_work_stacks_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6875
  assert(!_span.contains(addr), "we are scanning the survivor spaces");
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6876
  assert(p->klass_or_null() != NULL, "object should be initializd");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6877
  assert(p->is_parsable(), "must be parsable.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6878
  // an initialized object; ignore mark word in verification below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6879
  // since we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6880
  assert(p->is_oop(true), "should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6881
  // Note that we do not yield while we iterate over
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6882
  // the interior oops of p, pushing the relevant ones
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6883
  // on our marking stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6884
  size_t size = p->oop_iterate(_scanning_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6885
  do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6886
  // Observe that below, we do not abandon the preclean
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6887
  // phase as soon as we should; rather we empty the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6888
  // marking stack before returning. This is to satisfy
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6889
  // some existing assertions. In general, it may be a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6890
  // good idea to abort immediately and complete the marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6891
  // from the grey objects at a later time.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6892
  while (!_mark_stack->isEmpty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6893
    oop new_oop = _mark_stack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6894
    assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6895
    assert(new_oop->is_parsable(), "Found unparsable oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6896
    assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6897
           "only grey objects on this stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6898
    // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6899
    // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6900
    new_oop->oop_iterate(_scanning_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6901
    // check if it's time to yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6902
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6903
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6904
  unsigned int after_count =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6905
    GenCollectedHeap::heap()->total_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6906
  bool abort = (_before_count != after_count) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6907
               _collector->should_abort_preclean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6908
  return abort ? 0 : size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6909
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6910
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6911
void SurvivorSpacePrecleanClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6912
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6913
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6914
  assert_lock_strong(_bit_map->lock());
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  6915
  DEBUG_ONLY(RememberKlassesChecker smx(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6916
  // Relinquish the bit map lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6917
  _bit_map->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6918
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6919
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6920
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6921
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6922
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6923
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6924
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6925
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6926
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6927
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6928
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6929
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6930
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6931
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6932
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6933
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6934
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6935
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6936
  _bit_map->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6937
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6938
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6939
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6940
// This closure is used to rescan the marked objects on the dirty cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6941
// in the mod union table and the card table proper. In the parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6942
// case, although the bitMap is shared, we do a single read so the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6943
// isMarked() query is "safe".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6944
bool ScanMarkedObjectsAgainClosure::do_object_bm(oop p, MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6945
  // Ignore mark word because we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6946
  assert(p->is_oop_or_null(true), "expected an oop or null");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6947
  HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6948
  assert(_span.contains(addr), "we are scanning the CMS generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6949
  bool is_obj_array = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6950
  #ifdef DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6951
    if (!_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6952
      assert(_mark_stack->isEmpty(), "pre-condition (eager drainage)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6953
      assert(_collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6954
             "overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6955
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6956
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6957
  #endif // DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6958
  if (_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6959
    // Obj arrays are precisely marked, non-arrays are not;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6960
    // so we scan objArrays precisely and non-arrays in their
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6961
    // entirety.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6962
    if (p->is_objArray()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6963
      is_obj_array = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6964
      if (_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6965
        p->oop_iterate(_par_scan_closure, mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6966
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6967
        p->oop_iterate(_scan_closure, mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6968
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6969
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6970
      if (_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6971
        p->oop_iterate(_par_scan_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6972
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6973
        p->oop_iterate(_scan_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6974
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6975
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6976
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6977
  #ifdef DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6978
    if (!_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6979
      assert(_mark_stack->isEmpty(), "post-condition (eager drainage)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6980
      assert(_collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6981
             "overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6982
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6983
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6984
  #endif // DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6985
  return is_obj_array;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6986
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6987
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6988
MarkFromRootsClosure::MarkFromRootsClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6989
                        MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6990
                        CMSBitMap* bitMap, CMSMarkStack*  markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6991
                        CMSMarkStack*  revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6992
                        bool should_yield, bool verifying):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6993
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6994
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6995
  _bitMap(bitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6996
  _mut(&collector->_modUnionTable),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6997
  _markStack(markStack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6998
  _revisitStack(revisitStack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6999
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7000
  _skipBits(0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7001
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7002
  assert(_markStack->isEmpty(), "stack should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7003
  _finger = _bitMap->startWord();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7004
  _threshold = _finger;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7005
  assert(_collector->_restart_addr == NULL, "Sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7006
  assert(_span.contains(_finger), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7007
  DEBUG_ONLY(_verifying = verifying;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7008
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7009
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7010
void MarkFromRootsClosure::reset(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7011
  assert(_markStack->isEmpty(), "would cause duplicates on stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7012
  assert(_span.contains(addr), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7013
  _finger = addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7014
  _threshold = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7015
                 (intptr_t)_finger, CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7016
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7018
// Should revisit to see if this should be restructured for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7019
// greater efficiency.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7020
bool MarkFromRootsClosure::do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7021
  if (_skipBits > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7022
    _skipBits--;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7023
    return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7024
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7025
  // convert offset into a HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7026
  HeapWord* addr = _bitMap->startWord() + offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7027
  assert(_bitMap->endWord() && addr < _bitMap->endWord(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7028
         "address out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7029
  assert(_bitMap->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7030
  if (_bitMap->isMarked(addr+1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7031
    // this is an allocated but not yet initialized object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7032
    assert(_skipBits == 0, "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7033
    _skipBits = 2;  // skip next two marked bits ("Printezis-marks")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7034
    oop p = oop(addr);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  7035
    if (p->klass_or_null() == NULL || !p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7036
      DEBUG_ONLY(if (!_verifying) {)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7037
        // We re-dirty the cards on which this object lies and increase
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7038
        // the _threshold so that we'll come back to scan this object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7039
        // during the preclean or remark phase. (CMSCleanOnEnter)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7040
        if (CMSCleanOnEnter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7041
          size_t sz = _collector->block_size_using_printezis_bits(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7042
          HeapWord* end_card_addr   = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7043
                                         (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
  7044
          MemRegion redirty_range = MemRegion(addr, end_card_addr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7045
          assert(!redirty_range.is_empty(), "Arithmetical tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7046
          // Bump _threshold to end_card_addr; note that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7047
          // _threshold cannot possibly exceed end_card_addr, anyhow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7048
          // This prevents future clearing of the card as the scan proceeds
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7049
          // to the right.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7050
          assert(_threshold <= end_card_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7051
                 "Because we are just scanning into this object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7052
          if (_threshold < end_card_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7053
            _threshold = end_card_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7054
          }
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  7055
          if (p->klass_or_null() != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7056
            // Redirty the range of cards...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7057
            _mut->mark_range(redirty_range);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7058
          } // ...else the setting of klass will dirty the card anyway.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7059
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7060
      DEBUG_ONLY(})
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7061
      return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7062
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7063
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7064
  scanOopsInOop(addr);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7065
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7066
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7067
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7068
// We take a break if we've been at this for a while,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7069
// so as to avoid monopolizing the locks involved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7070
void MarkFromRootsClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7071
  // First give up the locks, then yield, then re-lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7072
  // We should probably use a constructor/destructor idiom to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7073
  // do this unlock/lock or modify the MutexUnlocker class to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7074
  // serve our purpose. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7075
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7076
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7077
  assert_lock_strong(_bitMap->lock());
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7078
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7079
  _bitMap->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7080
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7081
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7082
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7083
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7084
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7085
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7086
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7087
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7088
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7089
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7090
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7091
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7092
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7093
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7094
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7095
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7097
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7098
  _bitMap->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7099
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7100
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7101
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7102
void MarkFromRootsClosure::scanOopsInOop(HeapWord* ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7103
  assert(_bitMap->isMarked(ptr), "expected bit to be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7104
  assert(_markStack->isEmpty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7105
         "should drain stack to limit stack usage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7106
  // 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
  7107
  oop obj = oop(ptr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7108
  // Ignore mark word in verification below, since we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7109
  // 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
  7110
  assert(obj->is_oop(true), "should be an oop");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7111
  assert(_finger <= ptr, "_finger runneth ahead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7112
  // 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
  7113
  _finger = ptr + obj->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7114
  assert(_finger > ptr, "we just incremented it above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7115
  // On large heaps, it may take us some time to get through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7116
  // the marking phase (especially if running iCMS). During
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7117
  // this time it's possible that a lot of mutations have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7118
  // accumulated in the card table and the mod union table --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7119
  // these mutation records are redundant until we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7120
  // actually traced into the corresponding card.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7121
  // Here, we check whether advancing the finger would make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7122
  // us cross into a new card, and if so clear corresponding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7123
  // cards in the MUT (preclean them in the card-table in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7124
  // future).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7125
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7126
  DEBUG_ONLY(if (!_verifying) {)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7127
    // The clean-on-enter optimization is disabled by default,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7128
    // until we fix 6178663.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7129
    if (CMSCleanOnEnter && (_finger > _threshold)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7130
      // [_threshold, _finger) represents the interval
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7131
      // of cards to be cleared  in MUT (or precleaned in card table).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7132
      // The set of cards to be cleared is all those that overlap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7133
      // with the interval [_threshold, _finger); note that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7134
      // _threshold is always kept card-aligned but _finger isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7135
      // always card-aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7136
      HeapWord* old_threshold = _threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7137
      assert(old_threshold == (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7138
              (intptr_t)old_threshold, CardTableModRefBS::card_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7139
             "_threshold should always be card-aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7140
      _threshold = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7141
                     (intptr_t)_finger, CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7142
      MemRegion mr(old_threshold, _threshold);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7143
      assert(!mr.is_empty(), "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7144
      assert(_span.contains(mr), "Should clear within span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7145
      // XXX When _finger crosses from old gen into perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7146
      // we may be doing unnecessary cleaning; do better in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7147
      // future by detecting that condition and clearing fewer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7148
      // MUT/CT entries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7149
      _mut->clear_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7150
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7151
  DEBUG_ONLY(})
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7152
  // Note: the finger doesn't advance while we drain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7153
  // the stack below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7154
  PushOrMarkClosure pushOrMarkClosure(_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7155
                                      _span, _bitMap, _markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7156
                                      _revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7157
                                      _finger, this);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7158
  bool res = _markStack->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7159
  assert(res, "Empty non-zero size stack should have space for single push");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7160
  while (!_markStack->isEmpty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7161
    oop new_oop = _markStack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7162
    // Skip verifying header mark word below because we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7163
    // running concurrent with mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7164
    assert(new_oop->is_oop(true), "Oops! expected to pop an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7165
    // now scan this oop's oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7166
    new_oop->oop_iterate(&pushOrMarkClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7167
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7168
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7169
  assert(_markStack->isEmpty(), "tautology, emphasizing post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7170
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7171
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7172
Par_MarkFromRootsClosure::Par_MarkFromRootsClosure(CMSConcMarkingTask* task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7173
                       CMSCollector* collector, MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7174
                       CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7175
                       OopTaskQueue* work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7176
                       CMSMarkStack*  overflow_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7177
                       CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7178
                       bool should_yield):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7179
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7180
  _whole_span(collector->_span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7181
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7182
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7183
  _mut(&collector->_modUnionTable),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7184
  _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7185
  _overflow_stack(overflow_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7186
  _revisit_stack(revisit_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7187
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7188
  _skip_bits(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7189
  _task(task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7190
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7191
  assert(_work_queue->size() == 0, "work_queue should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7192
  _finger = span.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7193
  _threshold = _finger;     // XXX Defer clear-on-enter optimization for now
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7194
  assert(_span.contains(_finger), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7195
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7196
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7197
// Should revisit to see if this should be restructured for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7198
// greater efficiency.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7199
bool Par_MarkFromRootsClosure::do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7200
  if (_skip_bits > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7201
    _skip_bits--;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7202
    return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7203
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7204
  // convert offset into a HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7205
  HeapWord* addr = _bit_map->startWord() + offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7206
  assert(_bit_map->endWord() && addr < _bit_map->endWord(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7207
         "address out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7208
  assert(_bit_map->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7209
  if (_bit_map->isMarked(addr+1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7210
    // this is an allocated object that might not yet be initialized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7211
    assert(_skip_bits == 0, "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7212
    _skip_bits = 2;  // skip next two marked bits ("Printezis-marks")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7213
    oop p = oop(addr);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  7214
    if (p->klass_or_null() == NULL || !p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7215
      // in the case of Clean-on-Enter optimization, redirty card
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7216
      // and avoid clearing card by increasing  the threshold.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7217
      return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7218
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7219
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7220
  scan_oops_in_oop(addr);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7221
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7222
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7223
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7224
void Par_MarkFromRootsClosure::scan_oops_in_oop(HeapWord* ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7225
  assert(_bit_map->isMarked(ptr), "expected bit to be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7226
  // Should we assert that our work queue is empty or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7227
  // below some drain limit?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7228
  assert(_work_queue->size() == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7229
         "should drain stack to limit stack usage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7230
  // 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
  7231
  oop obj = oop(ptr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7232
  // Ignore mark word in verification below, since we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7233
  // 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
  7234
  assert(obj->is_oop(true), "should be an oop");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7235
  assert(_finger <= ptr, "_finger runneth ahead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7236
  // 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
  7237
  _finger = ptr + obj->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7238
  assert(_finger > ptr, "we just incremented it above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7239
  // On large heaps, it may take us some time to get through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7240
  // the marking phase (especially if running iCMS). During
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7241
  // this time it's possible that a lot of mutations have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7242
  // accumulated in the card table and the mod union table --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7243
  // these mutation records are redundant until we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7244
  // actually traced into the corresponding card.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7245
  // Here, we check whether advancing the finger would make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7246
  // us cross into a new card, and if so clear corresponding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7247
  // cards in the MUT (preclean them in the card-table in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7248
  // future).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7249
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7250
  // The clean-on-enter optimization is disabled by default,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7251
  // until we fix 6178663.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7252
  if (CMSCleanOnEnter && (_finger > _threshold)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7253
    // [_threshold, _finger) represents the interval
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7254
    // of cards to be cleared  in MUT (or precleaned in card table).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7255
    // The set of cards to be cleared is all those that overlap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7256
    // with the interval [_threshold, _finger); note that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7257
    // _threshold is always kept card-aligned but _finger isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7258
    // always card-aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7259
    HeapWord* old_threshold = _threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7260
    assert(old_threshold == (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7261
            (intptr_t)old_threshold, CardTableModRefBS::card_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7262
           "_threshold should always be card-aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7263
    _threshold = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7264
                   (intptr_t)_finger, CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7265
    MemRegion mr(old_threshold, _threshold);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7266
    assert(!mr.is_empty(), "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7267
    assert(_span.contains(mr), "Should clear within span"); // _whole_span ??
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7268
    // XXX When _finger crosses from old gen into perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7269
    // we may be doing unnecessary cleaning; do better in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7270
    // future by detecting that condition and clearing fewer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7271
    // MUT/CT entries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7272
    _mut->clear_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7273
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7274
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7275
  // Note: the local finger doesn't advance while we drain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7276
  // the stack below, but the global finger sure can and will.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7277
  HeapWord** gfa = _task->global_finger_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7278
  Par_PushOrMarkClosure pushOrMarkClosure(_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7279
                                      _span, _bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7280
                                      _work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7281
                                      _overflow_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7282
                                      _revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7283
                                      _finger,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7284
                                      gfa, this);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7285
  bool res = _work_queue->push(obj);   // overflow could occur here
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7286
  assert(res, "Will hold once we use workqueues");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7287
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7288
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7289
    if (!_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7290
      // We emptied our work_queue; check if there's stuff that can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7291
      // be gotten from the overflow stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7292
      if (CMSConcMarkingTask::get_work_from_overflow_stack(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7293
            _overflow_stack, _work_queue)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7294
        do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7295
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7296
      } else {  // done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7297
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7298
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7299
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7300
    // Skip verifying header mark word below because we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7301
    // running concurrent with mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7302
    assert(new_oop->is_oop(true), "Oops! expected to pop an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7303
    // now scan this oop's oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7304
    new_oop->oop_iterate(&pushOrMarkClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7305
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7306
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7307
  assert(_work_queue->size() == 0, "tautology, emphasizing post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7308
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7309
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7310
// Yield in response to a request from VM Thread or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7311
// from mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7312
void Par_MarkFromRootsClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7313
  assert(_task != NULL, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7314
  _task->yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7315
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7316
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7317
// A variant of the above used for verifying CMS marking work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7318
MarkFromRootsVerifyClosure::MarkFromRootsVerifyClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7319
                        MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7320
                        CMSBitMap* verification_bm, CMSBitMap* cms_bm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7321
                        CMSMarkStack*  mark_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7322
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7323
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7324
  _verification_bm(verification_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7325
  _cms_bm(cms_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7326
  _mark_stack(mark_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7327
  _pam_verify_closure(collector, span, verification_bm, cms_bm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7328
                      mark_stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7329
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7330
  assert(_mark_stack->isEmpty(), "stack should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7331
  _finger = _verification_bm->startWord();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7332
  assert(_collector->_restart_addr == NULL, "Sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7333
  assert(_span.contains(_finger), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7334
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7335
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7336
void MarkFromRootsVerifyClosure::reset(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7337
  assert(_mark_stack->isEmpty(), "would cause duplicates on stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7338
  assert(_span.contains(addr), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7339
  _finger = addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7340
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7341
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7342
// Should revisit to see if this should be restructured for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7343
// greater efficiency.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7344
bool MarkFromRootsVerifyClosure::do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7345
  // convert offset into a HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7346
  HeapWord* addr = _verification_bm->startWord() + offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7347
  assert(_verification_bm->endWord() && addr < _verification_bm->endWord(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7348
         "address out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7349
  assert(_verification_bm->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7350
  assert(_cms_bm->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7351
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7352
  assert(_mark_stack->isEmpty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7353
         "should drain stack to limit stack usage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7354
  // 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
  7355
  oop obj = oop(addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7356
  assert(obj->is_oop(), "should be an oop");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7357
  assert(_finger <= addr, "_finger runneth ahead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7358
  // 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
  7359
  _finger = addr + obj->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7360
  assert(_finger > addr, "we just incremented it above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7361
  // Note: the finger doesn't advance while we drain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7362
  // the stack below.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7363
  bool res = _mark_stack->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7364
  assert(res, "Empty non-zero size stack should have space for single push");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7365
  while (!_mark_stack->isEmpty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7366
    oop new_oop = _mark_stack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7367
    assert(new_oop->is_oop(), "Oops! expected to pop an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7368
    // now scan this oop's oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7369
    new_oop->oop_iterate(&_pam_verify_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7370
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7371
  assert(_mark_stack->isEmpty(), "tautology, emphasizing post-condition");
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7372
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7373
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7374
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7375
PushAndMarkVerifyClosure::PushAndMarkVerifyClosure(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7376
  CMSCollector* collector, MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7377
  CMSBitMap* verification_bm, CMSBitMap* cms_bm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7378
  CMSMarkStack*  mark_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7379
  OopClosure(collector->ref_processor()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7380
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7381
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7382
  _verification_bm(verification_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7383
  _cms_bm(cms_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7384
  _mark_stack(mark_stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7385
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7386
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7387
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
  7388
void PushAndMarkVerifyClosure::do_oop(narrowOop* p) { PushAndMarkVerifyClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7389
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7390
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7391
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7392
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7393
void PushAndMarkVerifyClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7394
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7395
  HeapWord* ra = (HeapWord*)_mark_stack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7396
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7397
  _mark_stack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7398
  _mark_stack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7399
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7400
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7401
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
  7402
  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
  7403
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7404
  if (_span.contains(addr) && !_verification_bm->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7405
    // Oop lies in _span and isn't yet grey or black
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7406
    _verification_bm->mark(addr);            // now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7407
    if (!_cms_bm->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7408
      oop(addr)->print();
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7409
      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
  7410
                             addr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7411
      fatal("... aborting");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7412
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7413
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7414
    if (!_mark_stack->push(obj)) { // stack overflow
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7415
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7416
        gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7417
                               SIZE_FORMAT, _mark_stack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7418
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7419
      assert(_mark_stack->isFull(), "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7420
      handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7421
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7422
    // anything including and to the right of _finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7423
    // will be scanned as we iterate over the remainder of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7424
    // bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7425
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7426
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7427
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7428
PushOrMarkClosure::PushOrMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7429
                     MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7430
                     CMSBitMap* bitMap, CMSMarkStack*  markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7431
                     CMSMarkStack*  revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7432
                     HeapWord* finger, MarkFromRootsClosure* parent) :
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7433
  KlassRememberingOopClosure(collector, collector->ref_processor(), revisitStack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7434
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7435
  _bitMap(bitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7436
  _markStack(markStack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7437
  _finger(finger),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7438
  _parent(parent)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7439
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7440
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7441
Par_PushOrMarkClosure::Par_PushOrMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7442
                     MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7443
                     CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7444
                     OopTaskQueue* work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7445
                     CMSMarkStack*  overflow_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7446
                     CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7447
                     HeapWord* finger,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7448
                     HeapWord** global_finger_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7449
                     Par_MarkFromRootsClosure* parent) :
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7450
  Par_KlassRememberingOopClosure(collector,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7451
                            collector->ref_processor(),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7452
                            revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7453
  _whole_span(collector->_span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7454
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7455
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7456
  _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7457
  _overflow_stack(overflow_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7458
  _finger(finger),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7459
  _global_finger_addr(global_finger_addr),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7460
  _parent(parent)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7461
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7462
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  7463
// Assumes thread-safe access by callers, who are
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  7464
// responsible for mutual exclusion.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7465
void CMSCollector::lower_restart_addr(HeapWord* low) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7466
  assert(_span.contains(low), "Out of bounds addr");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7467
  if (_restart_addr == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7468
    _restart_addr = low;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7469
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7470
    _restart_addr = MIN2(_restart_addr, low);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7471
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7472
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7473
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7474
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7475
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7476
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7477
void PushOrMarkClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7478
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7479
  HeapWord* ra = (HeapWord*)_markStack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7480
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7481
  _markStack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7482
  _markStack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7483
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7484
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7485
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7486
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7487
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7488
void Par_PushOrMarkClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7489
  // 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
  7490
  // workers from interfering with the work done below.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7491
  MutexLockerEx ml(_overflow_stack->par_lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7492
                   Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7493
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7494
  HeapWord* ra = (HeapWord*)_overflow_stack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7495
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7496
  _overflow_stack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7497
  _overflow_stack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7498
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7499
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7500
void PushOrMarkClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7501
  // 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
  7502
  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
  7503
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7504
  if (_span.contains(addr) && !_bitMap->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7505
    // Oop lies in _span and isn't yet grey or black
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7506
    _bitMap->mark(addr);            // now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7507
    if (addr < _finger) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7508
      // the bit map iteration has already either passed, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7509
      // sampled, this bit in the bit map; we'll need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7510
      // use the marking stack to scan this oop's oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7511
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7512
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7513
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7514
            _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7515
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7516
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7517
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7518
      )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7519
      if (simulate_overflow || !_markStack->push(obj)) { // stack overflow
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7520
        if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7521
          gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7522
                                 SIZE_FORMAT, _markStack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7523
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7524
        assert(simulate_overflow || _markStack->isFull(), "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7525
        handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7526
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7527
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7528
    // anything including and to the right of _finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7529
    // will be scanned as we iterate over the remainder of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7530
    // bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7531
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7532
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7533
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7534
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7535
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
  7536
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
  7537
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7538
void Par_PushOrMarkClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7539
  // 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
  7540
  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
  7541
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7542
  if (_whole_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7543
    // Oop lies in _span and isn't yet grey or black
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7544
    // We read the global_finger (volatile read) strictly after marking oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7545
    bool res = _bit_map->par_mark(addr);    // now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7546
    volatile HeapWord** gfa = (volatile HeapWord**)_global_finger_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7547
    // Should we push this marked oop on our stack?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7548
    // -- if someone else marked it, nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7549
    // -- if target oop is above global finger nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7550
    // -- if target oop is in chunk and above local finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7551
    //      then nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7552
    // -- else push on work queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7553
    if (   !res       // someone else marked it, they will deal with it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7554
        || (addr >= *gfa)  // will be scanned in a later task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7555
        || (_span.contains(addr) && addr >= _finger)) { // later in this chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7556
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7557
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7558
    // the bit map iteration has already either passed, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7559
    // sampled, this bit in the bit map; we'll need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7560
    // use the marking stack to scan this oop's oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7561
    bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7562
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7563
      if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7564
          _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7565
        // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7566
        simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7567
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7568
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7569
    if (simulate_overflow ||
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7570
        !(_work_queue->push(obj) || _overflow_stack->par_push(obj))) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7571
      // stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7572
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7573
        gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7574
                               SIZE_FORMAT, _overflow_stack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7575
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7576
      // We cannot assert that the overflow stack is full because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7577
      // it may have been emptied since.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7578
      assert(simulate_overflow ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7579
             _work_queue->size() == _work_queue->max_elems(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7580
            "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7581
      handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7582
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7583
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7584
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7585
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7586
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7587
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
  7588
void Par_PushOrMarkClosure::do_oop(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7589
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7590
KlassRememberingOopClosure::KlassRememberingOopClosure(CMSCollector* collector,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7591
                                             ReferenceProcessor* rp,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7592
                                             CMSMarkStack* revisit_stack) :
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7593
  OopClosure(rp),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7594
  _collector(collector),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7595
  _revisit_stack(revisit_stack),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7596
  _should_remember_klasses(collector->should_unload_classes()) {}
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7597
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7598
PushAndMarkClosure::PushAndMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7599
                                       MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7600
                                       ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7601
                                       CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7602
                                       CMSBitMap* mod_union_table,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7603
                                       CMSMarkStack*  mark_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7604
                                       CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7605
                                       bool           concurrent_precleaning):
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7606
  KlassRememberingOopClosure(collector, rp, revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7607
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7608
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7609
  _mod_union_table(mod_union_table),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7610
  _mark_stack(mark_stack),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7611
  _concurrent_precleaning(concurrent_precleaning)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7612
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7613
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7614
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7615
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7616
// Grey object rescan during pre-cleaning and second checkpoint phases --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7617
// 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
  7618
void PushAndMarkClosure::do_oop(oop obj) {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7619
  // Ignore mark word verification. If during concurrent precleaning,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7620
  // the object monitor may be locked. If during the checkpoint
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7621
  // 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
  7622
  // 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
  7623
  // the mark word may be NULL).
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7624
  assert(obj->is_oop_or_null(true /* ignore mark word */),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7625
         "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
  7626
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7627
  // Check if oop points into the CMS generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7628
  // and is not marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7629
  if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7630
    // a white object ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7631
    _bit_map->mark(addr);         // ... now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7632
    // push on the marking stack (grey set)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7633
    bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7634
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7635
      if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7636
          _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7637
        // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7638
        simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7639
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7640
    )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7641
    if (simulate_overflow || !_mark_stack->push(obj)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7642
      if (_concurrent_precleaning) {
991
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7643
         // During precleaning we can just dirty the appropriate card(s)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7644
         // 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
  7645
         // 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
  7646
         // 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
  7647
         // 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
  7648
         // dirty cards.
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7649
         // 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
  7650
         // 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
  7651
         // are required.
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7652
         if (obj->is_objArray()) {
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7653
           size_t sz = obj->size();
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7654
           HeapWord* end_card_addr = (HeapWord*)round_to(
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7655
                                        (intptr_t)(addr+sz), CardTableModRefBS::card_size);
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7656
           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
  7657
           assert(!redirty_range.is_empty(), "Arithmetical tautology");
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7658
           _mod_union_table->mark_range(redirty_range);
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7659
         } else {
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7660
           _mod_union_table->mark(addr);
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7661
         }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7662
         _collector->_ser_pmc_preclean_ovflw++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7663
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7664
         // During the remark phase, we need to remember this oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7665
         // in the overflow list.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7666
         _collector->push_on_overflow_list(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7667
         _collector->_ser_pmc_remark_ovflw++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7668
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7669
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7670
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7671
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7672
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7673
Par_PushAndMarkClosure::Par_PushAndMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7674
                                               MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7675
                                               ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7676
                                               CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7677
                                               OopTaskQueue* work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7678
                                               CMSMarkStack* revisit_stack):
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7679
  Par_KlassRememberingOopClosure(collector, rp, revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7680
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7681
  _bit_map(bit_map),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7682
  _work_queue(work_queue)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7683
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7684
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7685
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7686
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7687
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
  7688
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
  7689
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7690
// Grey object rescan during second checkpoint phase --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7691
// the parallel version.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7692
void Par_PushAndMarkClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7693
  // In the assert below, we ignore the mark word because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7694
  // this oop may point to an already visited object that is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7695
  // on the overflow stack (in which case the mark word has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7696
  // been hijacked for chaining into the overflow stack --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7697
  // if this is the last object in the overflow stack then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7698
  // its mark word will be NULL). Because this object may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7699
  // have been subsequently popped off the global overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7700
  // stack, and the mark word possibly restored to the prototypical
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7701
  // value, by the time we get to examined this failing assert in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7702
  // the debugger, is_oop_or_null(false) may subsequently start
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7703
  // to hold.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7704
  assert(obj->is_oop_or_null(true),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7705
         "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
  7706
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7707
  // Check if oop points into the CMS generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7708
  // and is not marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7709
  if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7710
    // a white object ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7711
    // If we manage to "claim" the object, by being the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7712
    // first thread to mark it, then we push it on our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7713
    // marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7714
    if (_bit_map->par_mark(addr)) {     // ... now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7715
      // push on work queue (grey set)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7716
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7717
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7718
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7719
            _collector->par_simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7720
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7721
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7722
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7723
      )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7724
      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
  7725
        _collector->par_push_on_overflow_list(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7726
        _collector->_par_pmc_remark_ovflw++; //  imprecise OK: no need to CAS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7727
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7728
    } // Else, some other thread got there first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7729
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7730
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7731
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7732
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
  7733
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
  7734
3696
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7735
void PushAndMarkClosure::remember_mdo(DataLayout* v) {
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7736
  // TBD
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7737
}
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7738
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7739
void Par_PushAndMarkClosure::remember_mdo(DataLayout* v) {
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7740
  // TBD
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7741
}
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7742
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7743
void CMSPrecleanRefsYieldClosure::do_yield_work() {
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7744
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7745
  Mutex* bml = _collector->bitMapLock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7746
  assert_lock_strong(bml);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7747
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7748
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7749
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7750
  bml->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7751
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7752
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7753
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7754
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7755
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7756
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7757
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7758
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7759
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7760
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7761
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7762
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7763
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7764
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7765
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7766
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7767
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7768
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7769
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7770
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7771
  bml->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7772
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7773
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7774
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7775
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7776
bool CMSPrecleanRefsYieldClosure::should_return() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7777
  if (ConcurrentMarkSweepThread::should_yield()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7778
    do_yield_work();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7779
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7780
  return _collector->foregroundGCIsActive();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7781
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7782
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7783
void MarkFromDirtyCardsClosure::do_MemRegion(MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7784
  assert(((size_t)mr.start())%CardTableModRefBS::card_size_in_words == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7785
         "mr should be aligned to start at a card boundary");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7786
  // We'd like to assert:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7787
  // assert(mr.word_size()%CardTableModRefBS::card_size_in_words == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7788
  //        "mr should be a range of cards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7789
  // However, that would be too strong in one case -- the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7790
  // partition ends at _unallocated_block which, in general, can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7791
  // an arbitrary boundary, not necessarily card aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7792
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7793
    _num_dirty_cards +=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7794
         mr.word_size()/CardTableModRefBS::card_size_in_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7795
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7796
  _space->object_iterate_mem(mr, &_scan_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7797
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7798
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7799
SweepClosure::SweepClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7800
                           ConcurrentMarkSweepGeneration* g,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7801
                           CMSBitMap* bitMap, bool should_yield) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7802
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7803
  _g(g),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7804
  _sp(g->cmsSpace()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7805
  _limit(_sp->sweep_limit()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7806
  _freelistLock(_sp->freelistLock()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7807
  _bitMap(bitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7808
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7809
  _inFreeRange(false),           // No free range at beginning of sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7810
  _freeRangeInFreeLists(false),  // No free range at beginning of sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7811
  _lastFreeRangeCoalesced(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7812
  _freeFinger(g->used_region().start())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7813
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7814
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7815
    _numObjectsFreed = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7816
    _numWordsFreed   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7817
    _numObjectsLive = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7818
    _numWordsLive = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7819
    _numObjectsAlreadyFree = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7820
    _numWordsAlreadyFree = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7821
    _last_fc = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7822
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7823
    _sp->initializeIndexedFreeListArrayReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7824
    _sp->dictionary()->initializeDictReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7825
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7826
  assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7827
         "sweep _limit out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7828
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7829
    gclog_or_tty->print("\n====================\nStarting new sweep\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7830
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7831
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7832
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7833
// We need this destructor to reclaim any space at the end
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7834
// of the space, which do_blk below may not have added back to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7835
// the free lists. [basically dealing with the "fringe effect"]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7836
SweepClosure::~SweepClosure() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7837
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7838
  // this should be treated as the end of a free run if any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7839
  // The current free range should be returned to the free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7840
  // as one coalesced chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7841
  if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7842
    flushCurFreeChunk(freeFinger(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7843
      pointer_delta(_limit, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7844
    assert(freeFinger() < _limit, "the finger pointeth off base");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7845
    if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7846
      gclog_or_tty->print("destructor:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7847
      gclog_or_tty->print("Sweep:put_free_blk 0x%x ("SIZE_FORMAT") "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7848
                 "[coalesced:"SIZE_FORMAT"]\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7849
                 freeFinger(), pointer_delta(_limit, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7850
                 lastFreeRangeCoalesced());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7851
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7852
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7853
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7854
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7855
      gclog_or_tty->print("Collected "SIZE_FORMAT" objects, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7856
                          SIZE_FORMAT " bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7857
                 _numObjectsFreed, _numWordsFreed*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7858
      gclog_or_tty->print_cr("\nLive "SIZE_FORMAT" objects,  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7859
                             SIZE_FORMAT" bytes  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7860
        "Already free "SIZE_FORMAT" objects, "SIZE_FORMAT" bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7861
        _numObjectsLive, _numWordsLive*sizeof(HeapWord),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7862
        _numObjectsAlreadyFree, _numWordsAlreadyFree*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7863
      size_t totalBytes = (_numWordsFreed + _numWordsLive + _numWordsAlreadyFree) *
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7864
        sizeof(HeapWord);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7865
      gclog_or_tty->print_cr("Total sweep: "SIZE_FORMAT" bytes", totalBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7866
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7867
      if (PrintCMSStatistics && CMSVerifyReturnedBytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7868
        size_t indexListReturnedBytes = _sp->sumIndexedFreeListArrayReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7869
        size_t dictReturnedBytes = _sp->dictionary()->sumDictReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7870
        size_t returnedBytes = indexListReturnedBytes + dictReturnedBytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7871
        gclog_or_tty->print("Returned "SIZE_FORMAT" bytes", returnedBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7872
        gclog_or_tty->print("   Indexed List Returned "SIZE_FORMAT" bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7873
          indexListReturnedBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7874
        gclog_or_tty->print_cr("        Dictionary Returned "SIZE_FORMAT" bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7875
          dictReturnedBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7876
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7877
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7878
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7879
  // Now, in debug mode, just null out the sweep_limit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7880
  NOT_PRODUCT(_sp->clear_sweep_limit();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7881
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7882
    gclog_or_tty->print("end of sweep\n================\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7883
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7884
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7885
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7886
void SweepClosure::initialize_free_range(HeapWord* freeFinger,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7887
    bool freeRangeInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7888
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7889
    gclog_or_tty->print("---- Start free range 0x%x with free block [%d] (%d)\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7890
               freeFinger, _sp->block_size(freeFinger),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7891
               freeRangeInFreeLists);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7892
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7893
  assert(!inFreeRange(), "Trampling existing free range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7894
  set_inFreeRange(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7895
  set_lastFreeRangeCoalesced(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7896
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7897
  set_freeFinger(freeFinger);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7898
  set_freeRangeInFreeLists(freeRangeInFreeLists);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7899
  if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7900
    if (freeRangeInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7901
      FreeChunk* fc = (FreeChunk*) freeFinger;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7902
      assert(fc->isFree(), "A chunk on the free list should be free.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7903
      assert(fc->size() > 0, "Free range should have a size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7904
      assert(_sp->verifyChunkInFreeLists(fc), "Chunk is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7905
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7906
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7907
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7908
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7909
// Note that the sweeper runs concurrently with mutators. Thus,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7910
// it is possible for direct allocation in this generation to happen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7911
// in the middle of the sweep. Note that the sweeper also coalesces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7912
// contiguous free blocks. Thus, unless the sweeper and the allocator
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7913
// synchronize appropriately freshly allocated blocks may get swept up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7914
// This is accomplished by the sweeper locking the free lists while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7915
// it is sweeping. Thus blocks that are determined to be free are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7916
// indeed free. There is however one additional complication:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7917
// blocks that have been allocated since the final checkpoint and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7918
// mark, will not have been marked and so would be treated as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7919
// unreachable and swept up. To prevent this, the allocator marks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7920
// the bit map when allocating during the sweep phase. This leads,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7921
// however, to a further complication -- objects may have been allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7922
// but not yet initialized -- in the sense that the header isn't yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7923
// installed. The sweeper can not then determine the size of the block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7924
// in order to skip over it. To deal with this case, we use a technique
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7925
// (due to Printezis) to encode such uninitialized block sizes in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7926
// bit map. Since the bit map uses a bit per every HeapWord, but the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7927
// CMS generation has a minimum object size of 3 HeapWords, it follows
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7928
// that "normal marks" won't be adjacent in the bit map (there will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7929
// always be at least two 0 bits between successive 1 bits). We make use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7930
// of these "unused" bits to represent uninitialized blocks -- the bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7931
// corresponding to the start of the uninitialized object and the next
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7932
// bit are both set. Finally, a 1 bit marks the end of the object that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7933
// started with the two consecutive 1 bits to indicate its potentially
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7934
// uninitialized state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7935
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7936
size_t SweepClosure::do_blk_careful(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7937
  FreeChunk* fc = (FreeChunk*)addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7938
  size_t res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7939
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7940
  // check if we are done sweepinrg
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7941
  if (addr == _limit) { // we have swept up to the limit, do nothing more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7942
    assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7943
           "sweep _limit out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7944
    // help the closure application finish
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7945
    return pointer_delta(_sp->end(), _limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7946
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7947
  assert(addr <= _limit, "sweep invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7948
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7949
  // check if we should yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7950
  do_yield_check(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7951
  if (fc->isFree()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7952
    // Chunk that is already free
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7953
    res = fc->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7954
    doAlreadyFreeChunk(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7955
    debug_only(_sp->verifyFreeLists());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7956
    assert(res == fc->size(), "Don't expect the size to change");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7957
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7958
      _numObjectsAlreadyFree++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7959
      _numWordsAlreadyFree += res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7960
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7961
    NOT_PRODUCT(_last_fc = fc;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7962
  } else if (!_bitMap->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7963
    // Chunk is fresh garbage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7964
    res = doGarbageChunk(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7965
    debug_only(_sp->verifyFreeLists());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7966
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7967
      _numObjectsFreed++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7968
      _numWordsFreed += res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7969
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7970
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7971
    // Chunk that is alive.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7972
    res = doLiveChunk(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7973
    debug_only(_sp->verifyFreeLists());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7974
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7975
        _numObjectsLive++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7976
        _numWordsLive += res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7977
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7978
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7979
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7980
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7981
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7982
// For the smart allocation, record following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7983
//  split deaths - a free chunk is removed from its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7984
//      it is being split into two or more chunks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7985
//  split birth - a free chunk is being added to its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7986
//      a larger free chunk has been split and resulted in this free chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7987
//  coal death - a free chunk is being removed from its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7988
//      it is being coalesced into a large free chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7989
//  coal birth - a free chunk is being added to its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7990
//      it was created when two or more free chunks where coalesced into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7991
//      this free chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7992
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7993
// These statistics are used to determine the desired number of free
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7994
// chunks of a given size.  The desired number is chosen to be relative
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7995
// to the end of a CMS sweep.  The desired number at the end of a sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7996
// is the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7997
//      count-at-end-of-previous-sweep (an amount that was enough)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7998
//              - count-at-beginning-of-current-sweep  (the excess)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7999
//              + split-births  (gains in this size during interval)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8000
//              - split-deaths  (demands on this size during interval)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8001
// where the interval is from the end of one sweep to the end of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8002
// next.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8003
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8004
// When sweeping the sweeper maintains an accumulated chunk which is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8005
// the chunk that is made up of chunks that have been coalesced.  That
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8006
// will be termed the left-hand chunk.  A new chunk of garbage that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8007
// is being considered for coalescing will be referred to as the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8008
// right-hand chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8009
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8010
// When making a decision on whether to coalesce a right-hand chunk with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8011
// the current left-hand chunk, the current count vs. the desired count
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8012
// of the left-hand chunk is considered.  Also if the right-hand chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8013
// is near the large chunk at the end of the heap (see
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8014
// ConcurrentMarkSweepGeneration::isNearLargestChunk()), then the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8015
// left-hand chunk is coalesced.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8016
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8017
// When making a decision about whether to split a chunk, the desired count
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8018
// vs. the current count of the candidate to be split is also considered.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8019
// If the candidate is underpopulated (currently fewer chunks than desired)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8020
// a chunk of an overpopulated (currently more chunks than desired) size may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8021
// be chosen.  The "hint" associated with a free list, if non-null, points
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8022
// to a free list which may be overpopulated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8023
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8024
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8025
void SweepClosure::doAlreadyFreeChunk(FreeChunk* fc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8026
  size_t size = fc->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8027
  // Chunks that cannot be coalesced are not in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8028
  // free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8029
  if (CMSTestInFreeList && !fc->cantCoalesce()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8030
    assert(_sp->verifyChunkInFreeLists(fc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8031
      "free chunk should be in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8032
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8033
  // a chunk that is already free, should not have been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8034
  // marked in the bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8035
  HeapWord* addr = (HeapWord*) fc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8036
  assert(!_bitMap->isMarked(addr), "free chunk should be unmarked");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8037
  // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8038
  // addr and purported end of this block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8039
  _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8040
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8041
  // Some chunks cannot be coalesced in under any circumstances.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8042
  // See the definition of cantCoalesce().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8043
  if (!fc->cantCoalesce()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8044
    // This chunk can potentially be coalesced.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8045
    if (_sp->adaptive_freelists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8046
      // All the work is done in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8047
      doPostIsFreeOrGarbageChunk(fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8048
    } else {  // Not adaptive free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8049
      // this is a free chunk that can potentially be coalesced by the sweeper;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8050
      if (!inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8051
        // if the next chunk is a free block that can't be coalesced
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8052
        // it doesn't make sense to remove this chunk from the free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8053
        FreeChunk* nextChunk = (FreeChunk*)(addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8054
        assert((HeapWord*)nextChunk <= _limit, "sweep invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8055
        if ((HeapWord*)nextChunk < _limit  &&    // there's a next chunk...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8056
            nextChunk->isFree()    &&            // which is free...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8057
            nextChunk->cantCoalesce()) {         // ... but cant be coalesced
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8058
          // nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8059
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8060
          // Potentially the start of a new free range:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8061
          // Don't eagerly remove it from the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8062
          // No need to remove it if it will just be put
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8063
          // back again.  (Also from a pragmatic point of view
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8064
          // if it is a free block in a region that is beyond
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8065
          // any allocated blocks, an assertion will fail)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8066
          // Remember the start of a free run.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8067
          initialize_free_range(addr, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8068
          // end - can coalesce with next chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8069
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8070
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8071
        // the midst of a free range, we are coalescing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8072
        debug_only(record_free_block_coalesced(fc);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8073
        if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8074
          gclog_or_tty->print("  -- pick up free block 0x%x (%d)\n", fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8075
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8076
        // remove it from the free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8077
        _sp->removeFreeChunkFromFreeLists(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8078
        set_lastFreeRangeCoalesced(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8079
        // If the chunk is being coalesced and the current free range is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8080
        // in the free lists, remove the current free range so that it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8081
        // will be returned to the free lists in its entirety - all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8082
        // the coalesced pieces included.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8083
        if (freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8084
          FreeChunk* ffc = (FreeChunk*) freeFinger();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8085
          assert(ffc->size() == pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8086
            "Size of free range is inconsistent with chunk size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8087
          if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8088
            assert(_sp->verifyChunkInFreeLists(ffc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8089
              "free range is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8090
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8091
          _sp->removeFreeChunkFromFreeLists(ffc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8092
          set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8093
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8094
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8095
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8096
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8097
    // Code path common to both original and adaptive free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8098
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8099
    // cant coalesce with previous block; this should be treated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8100
    // as the end of a free run if any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8101
    if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8102
      // we kicked some butt; time to pick up the garbage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8103
      assert(freeFinger() < addr, "the finger pointeth off base");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8104
      flushCurFreeChunk(freeFinger(), pointer_delta(addr, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8105
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8106
    // else, nothing to do, just continue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8107
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8108
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8109
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8110
size_t SweepClosure::doGarbageChunk(FreeChunk* fc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8111
  // This is a chunk of garbage.  It is not in any free list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8112
  // Add it to a free list or let it possibly be coalesced into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8113
  // a larger chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8114
  HeapWord* addr = (HeapWord*) fc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8115
  size_t size = CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8116
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8117
  if (_sp->adaptive_freelists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8118
    // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8119
    // addr and purported end of just dead object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8120
    _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8121
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8122
    doPostIsFreeOrGarbageChunk(fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8123
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8124
    if (!inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8125
      // start of a new free range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8126
      assert(size > 0, "A free range should have a size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8127
      initialize_free_range(addr, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8128
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8129
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8130
      // this will be swept up when we hit the end of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8131
      // free range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8132
      if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8133
        gclog_or_tty->print("  -- pick up garbage 0x%x (%d) \n", fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8134
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8135
      // If the chunk is being coalesced and the current free range is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8136
      // in the free lists, remove the current free range so that it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8137
      // will be returned to the free lists in its entirety - all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8138
      // the coalesced pieces included.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8139
      if (freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8140
        FreeChunk* ffc = (FreeChunk*)freeFinger();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8141
        assert(ffc->size() == pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8142
          "Size of free range is inconsistent with chunk size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8143
        if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8144
          assert(_sp->verifyChunkInFreeLists(ffc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8145
            "free range is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8146
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8147
        _sp->removeFreeChunkFromFreeLists(ffc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8148
        set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8149
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8150
      set_lastFreeRangeCoalesced(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8151
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8152
    // this will be swept up when we hit the end of the free range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8153
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8154
    // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8155
    // addr and purported end of just dead object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8156
    _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8157
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8158
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8159
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8160
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8161
size_t SweepClosure::doLiveChunk(FreeChunk* fc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8162
  HeapWord* addr = (HeapWord*) fc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8163
  // The sweeper has just found a live object. Return any accumulated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8164
  // left hand chunk to the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8165
  if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8166
    if (_sp->adaptive_freelists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8167
      flushCurFreeChunk(freeFinger(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8168
                        pointer_delta(addr, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8169
    } else { // not adaptive freelists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8170
      set_inFreeRange(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8171
      // Add the free range back to the free list if it is not already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8172
      // there.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8173
      if (!freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8174
        assert(freeFinger() < addr, "the finger pointeth off base");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8175
        if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8176
          gclog_or_tty->print("Sweep:put_free_blk 0x%x (%d) "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8177
            "[coalesced:%d]\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8178
            freeFinger(), pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8179
            lastFreeRangeCoalesced());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8180
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8181
        _sp->addChunkAndRepairOffsetTable(freeFinger(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8182
          pointer_delta(addr, freeFinger()), lastFreeRangeCoalesced());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8183
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8184
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8185
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8186
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8187
  // Common code path for original and adaptive free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8188
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8189
  // this object is live: we'd normally expect this to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8190
  // an oop, and like to assert the following:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8191
  // assert(oop(addr)->is_oop(), "live block should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8192
  // However, as we commented above, this may be an object whose
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8193
  // header hasn't yet been initialized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8194
  size_t size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8195
  assert(_bitMap->isMarked(addr), "Tautology for this control point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8196
  if (_bitMap->isMarked(addr + 1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8197
    // Determine the size from the bit map, rather than trying to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8198
    // compute it from the object header.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8199
    HeapWord* nextOneAddr = _bitMap->getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8200
    size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8201
    assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8202
           "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8203
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8204
    #ifdef DEBUG
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  8205
      if (oop(addr)->klass_or_null() != NULL &&
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  8206
          (   !_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
  8207
           || (oop(addr)->is_parsable()) &&
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8208
               oop(addr)->is_conc_safe())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8209
        // Ignore mark word because we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8210
        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
  8211
        // 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
  8212
        // 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
  8213
        // the return from size() correct.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8214
        assert(size ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8215
               CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8216
               "P-mark and computed size do not agree");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8217
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8218
    #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8219
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8220
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8221
    // This should be an initialized object that's alive.
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  8222
    assert(oop(addr)->klass_or_null() != NULL &&
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  8223
           (!_collector->should_unload_classes()
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8224
            || oop(addr)->is_parsable()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8225
           "Should be an initialized object");
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8226
    // Note that there are objects used during class redefinition
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8227
    // (e.g., merge_cp in VM_RedefineClasses::merge_cp_and_rewrite()
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8228
    // 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
  8229
    // 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
  8230
    // 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
  8231
    // 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
  8232
    // is_conc_safe() is true for oop(addr).
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8233
    // Ignore mark word because we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8234
    assert(oop(addr)->is_oop(true), "live block should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8235
    // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8236
    // addr and purported end of this block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8237
    size = CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8238
    assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8239
    assert(!_bitMap->isMarked(addr+1), "Tautology for this control point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8240
    DEBUG_ONLY(_bitMap->verifyNoOneBitsInRange(addr+2, addr+size);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8241
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8242
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8243
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8245
void SweepClosure::doPostIsFreeOrGarbageChunk(FreeChunk* fc,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8246
                                            size_t chunkSize) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8247
  // doPostIsFreeOrGarbageChunk() should only be called in the smart allocation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8248
  // scheme.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8249
  bool fcInFreeLists = fc->isFree();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8250
  assert(_sp->adaptive_freelists(), "Should only be used in this case.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8251
  assert((HeapWord*)fc <= _limit, "sweep invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8252
  if (CMSTestInFreeList && fcInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8253
    assert(_sp->verifyChunkInFreeLists(fc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8254
      "free chunk is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8255
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8256
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8257
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8258
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8259
    gclog_or_tty->print_cr("  -- pick up another chunk at 0x%x (%d)", fc, chunkSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8260
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8261
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8262
  HeapWord* addr = (HeapWord*) fc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8263
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8264
  bool coalesce;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8265
  size_t left  = pointer_delta(addr, freeFinger());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8266
  size_t right = chunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8267
  switch (FLSCoalescePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8268
    // numeric value forms a coalition aggressiveness metric
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8269
    case 0:  { // never coalesce
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8270
      coalesce = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8271
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8272
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8273
    case 1: { // coalesce if left & right chunks on overpopulated lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8274
      coalesce = _sp->coalOverPopulated(left) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8275
                 _sp->coalOverPopulated(right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8276
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8277
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8278
    case 2: { // coalesce if left chunk on overpopulated list (default)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8279
      coalesce = _sp->coalOverPopulated(left);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8280
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8281
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8282
    case 3: { // coalesce if left OR right chunk on overpopulated list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8283
      coalesce = _sp->coalOverPopulated(left) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8284
                 _sp->coalOverPopulated(right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8285
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8286
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8287
    case 4: { // always coalesce
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8288
      coalesce = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8289
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8290
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8291
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8292
     ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8293
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8295
  // Should the current free range be coalesced?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8296
  // If the chunk is in a free range and either we decided to coalesce above
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8297
  // or the chunk is near the large block at the end of the heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8298
  // (isNearLargestChunk() returns true), then coalesce this chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8299
  bool doCoalesce = inFreeRange() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8300
    (coalesce || _g->isNearLargestChunk((HeapWord*)fc));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8301
  if (doCoalesce) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8302
    // Coalesce the current free range on the left with the new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8303
    // chunk on the right.  If either is on a free list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8304
    // it must be removed from the list and stashed in the closure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8305
    if (freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8306
      FreeChunk* ffc = (FreeChunk*)freeFinger();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8307
      assert(ffc->size() == pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8308
        "Size of free range is inconsistent with chunk size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8309
      if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8310
        assert(_sp->verifyChunkInFreeLists(ffc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8311
          "Chunk is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8312
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8313
      _sp->coalDeath(ffc->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8314
      _sp->removeFreeChunkFromFreeLists(ffc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8315
      set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8316
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8317
    if (fcInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8318
      _sp->coalDeath(chunkSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8319
      assert(fc->size() == chunkSize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8320
        "The chunk has the wrong size or is not in the free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8321
      _sp->removeFreeChunkFromFreeLists(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8322
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8323
    set_lastFreeRangeCoalesced(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8324
  } else {  // not in a free range and/or should not coalesce
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8325
    // Return the current free range and start a new one.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8326
    if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8327
      // In a free range but cannot coalesce with the right hand chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8328
      // Put the current free range into the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8329
      flushCurFreeChunk(freeFinger(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8330
        pointer_delta(addr, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8331
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8332
    // Set up for new free range.  Pass along whether the right hand
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8333
    // chunk is in the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8334
    initialize_free_range((HeapWord*)fc, fcInFreeLists);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8335
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8336
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8337
void SweepClosure::flushCurFreeChunk(HeapWord* chunk, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8338
  assert(inFreeRange(), "Should only be called if currently in a free range.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8339
  assert(size > 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8340
    "A zero sized chunk cannot be added to the free lists.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8341
  if (!freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8342
    if(CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8343
      FreeChunk* fc = (FreeChunk*) chunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8344
      fc->setSize(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8345
      assert(!_sp->verifyChunkInFreeLists(fc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8346
        "chunk should not be in free lists yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8347
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8348
    if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8349
      gclog_or_tty->print_cr(" -- add free block 0x%x (%d) to free lists",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8350
                    chunk, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8351
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8352
    // A new free range is going to be starting.  The current
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8353
    // free range has not been added to the free lists yet or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8354
    // was removed so add it back.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8355
    // If the current free range was coalesced, then the death
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8356
    // of the free range was recorded.  Record a birth now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8357
    if (lastFreeRangeCoalesced()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8358
      _sp->coalBirth(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8359
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8360
    _sp->addChunkAndRepairOffsetTable(chunk, size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8361
            lastFreeRangeCoalesced());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8362
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8363
  set_inFreeRange(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8364
  set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8365
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8366
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8367
// We take a break if we've been at this for a while,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8368
// so as to avoid monopolizing the locks involved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8369
void SweepClosure::do_yield_work(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8370
  // Return current free chunk being used for coalescing (if any)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8371
  // to the appropriate freelist.  After yielding, the next
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8372
  // free block encountered will start a coalescing range of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8373
  // free blocks.  If the next free block is adjacent to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8374
  // chunk just flushed, they will need to wait for the next
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8375
  // sweep to be coalesced.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8376
  if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8377
    flushCurFreeChunk(freeFinger(), pointer_delta(addr, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8378
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8379
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8380
  // First give up the locks, then yield, then re-lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8381
  // We should probably use a constructor/destructor idiom to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8382
  // do this unlock/lock or modify the MutexUnlocker class to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8383
  // serve our purpose. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8384
  assert_lock_strong(_bitMap->lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8385
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8386
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8387
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8388
  _bitMap->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8389
  _freelistLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8390
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8391
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8392
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8393
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8394
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8395
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8396
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8397
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8398
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8399
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8400
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8401
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8402
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8403
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8404
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8405
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8406
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8407
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8408
  _freelistLock->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8409
  _bitMap->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8410
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8411
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8412
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8413
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8414
// This is actually very useful in a product build if it can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8415
// be called from the debugger.  Compile it into the product
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8416
// as needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8417
bool debug_verifyChunkInFreeLists(FreeChunk* fc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8418
  return debug_cms_space->verifyChunkInFreeLists(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8419
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8420
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8421
void SweepClosure::record_free_block_coalesced(FreeChunk* fc) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8422
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8423
    gclog_or_tty->print("Sweep:coal_free_blk 0x%x (%d)\n", fc, fc->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8424
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8425
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8426
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8427
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8428
// CMSIsAliveClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8429
bool CMSIsAliveClosure::do_object_b(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8430
  HeapWord* addr = (HeapWord*)obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8431
  return addr != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8432
         (!_span.contains(addr) || _bit_map->isMarked(addr));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8433
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8434
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8435
CMSKeepAliveClosure::CMSKeepAliveClosure( CMSCollector* collector,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8436
                      MemRegion span,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8437
                      CMSBitMap* bit_map, CMSMarkStack* mark_stack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8438
                      CMSMarkStack* revisit_stack, bool cpc):
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8439
  KlassRememberingOopClosure(collector, NULL, revisit_stack),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8440
  _span(span),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8441
  _bit_map(bit_map),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8442
  _mark_stack(mark_stack),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8443
  _concurrent_precleaning(cpc) {
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8444
  assert(!_span.is_empty(), "Empty span could spell trouble");
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8445
}
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8446
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8447
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8448
// CMSKeepAliveClosure: the serial version
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8449
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
  8450
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8451
  if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8452
      !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8453
    _bit_map->mark(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8454
    bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8455
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8456
      if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8457
          _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8458
        // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8459
        simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8460
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8461
    )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8462
    if (simulate_overflow || !_mark_stack->push(obj)) {
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8463
      if (_concurrent_precleaning) {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8464
        // 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
  8465
        // phase deal with it.
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8466
        assert(_collector->overflow_list_is_empty(), "Error");
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8467
        // 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
  8468
        // 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
  8469
        // 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
  8470
        // table.
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8471
        if (obj->is_objArray()) {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8472
          size_t sz = obj->size();
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8473
          HeapWord* end_card_addr =
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8474
            (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
  8475
          MemRegion redirty_range = MemRegion(addr, end_card_addr);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8476
          assert(!redirty_range.is_empty(), "Arithmetical tautology");
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8477
          _collector->_modUnionTable.mark_range(redirty_range);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8478
        } else {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8479
          _collector->_modUnionTable.mark(addr);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8480
        }
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8481
        _collector->_ser_kac_preclean_ovflw++;
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8482
      } else {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8483
        _collector->push_on_overflow_list(obj);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8484
        _collector->_ser_kac_ovflw++;
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8485
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8486
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8487
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8488
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8489
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8490
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
  8491
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
  8492
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8493
// CMSParKeepAliveClosure: a parallel version of the above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8494
// The work queues are private to each closure (thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8495
// 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
  8496
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
  8497
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8498
  if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8499
      !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8500
    // In general, during recursive tracing, several threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8501
    // may be concurrently getting here; the first one to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8502
    // "tag" it, claims it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8503
    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
  8504
      bool res = _work_queue->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8505
      assert(res, "Low water mark should be much less than capacity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8506
      // Do a recursive trim in the hope that this will keep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8507
      // stack usage lower, but leave some oops for potential stealers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8508
      trim_queue(_low_water_mark);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8509
    } // Else, another thread got there first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8510
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8511
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8512
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8513
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
  8514
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
  8515
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8516
void CMSParKeepAliveClosure::trim_queue(uint max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8517
  while (_work_queue->size() > max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8518
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8519
    if (_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8520
      assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8521
      assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8522
             "no white objects on this stack!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8523
      assert(_span.contains((HeapWord*)new_oop), "Out of bounds oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8524
      // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8525
      // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8526
      new_oop->oop_iterate(&_mark_and_push);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8527
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8528
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8529
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8530
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8531
CMSInnerParMarkAndPushClosure::CMSInnerParMarkAndPushClosure(
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8532
                                CMSCollector* collector,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8533
                                MemRegion span, CMSBitMap* bit_map,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8534
                                CMSMarkStack* revisit_stack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8535
                                OopTaskQueue* work_queue):
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8536
  Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8537
  _span(span),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8538
  _bit_map(bit_map),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8539
  _work_queue(work_queue) { }
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8540
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8541
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
  8542
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8543
  if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8544
      !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8545
    if (_bit_map->par_mark(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8546
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8547
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8548
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8549
            _collector->par_simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8550
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8551
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8552
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8553
      )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8554
      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
  8555
        _collector->par_push_on_overflow_list(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8556
        _collector->_par_kac_ovflw++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8557
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8558
    } // Else another thread got there already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8559
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8560
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8561
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8562
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
  8563
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
  8564
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8565
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8566
//  CMSExpansionCause                /////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8567
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8568
const char* CMSExpansionCause::to_string(CMSExpansionCause::Cause cause) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8569
  switch (cause) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8570
    case _no_expansion:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8571
      return "No expansion";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8572
    case _satisfy_free_ratio:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8573
      return "Free ratio";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8574
    case _satisfy_promotion:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8575
      return "Satisfy promotion";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8576
    case _satisfy_allocation:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8577
      return "allocation";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8578
    case _allocate_par_lab:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8579
      return "Par LAB";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8580
    case _allocate_par_spooling_space:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8581
      return "Par Spooling Space";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8582
    case _adaptive_size_policy:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8583
      return "Ergonomics";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8584
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8585
      return "unknown";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8586
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8587
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8588
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8589
void CMSDrainMarkingStackClosure::do_void() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8590
  // the max number to take from overflow list at a time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8591
  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
  8592
  assert(!_concurrent_precleaning || _collector->overflow_list_is_empty(),
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8593
         "Overflow list should be NULL during concurrent phases");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8594
  while (!_mark_stack->isEmpty() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8595
         // if stack is empty, check the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8596
         _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
  8597
    oop obj = _mark_stack->pop();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8598
    HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8599
    assert(_span.contains(addr), "Should be within span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8600
    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
  8601
    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
  8602
    obj->oop_iterate(_keep_alive);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8603
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8604
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8605
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8606
void CMSParDrainMarkingStackClosure::do_void() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8607
  // drain queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8608
  trim_queue(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8609
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8610
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8611
// Trim our work_queue so its length is below max at return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8612
void CMSParDrainMarkingStackClosure::trim_queue(uint max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8613
  while (_work_queue->size() > max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8614
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8615
    if (_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8616
      assert(new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8617
      assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8618
             "no white objects on this stack!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8619
      assert(_span.contains((HeapWord*)new_oop), "Out of bounds oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8620
      // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8621
      // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8622
      new_oop->oop_iterate(&_mark_and_push);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8623
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8624
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8625
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8626
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8627
////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8628
// Support for Marking Stack Overflow list handling and related code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8629
////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8630
// Much of the following code is similar in shape and spirit to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8631
// code used in ParNewGC. We should try and share that code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8632
// as much as possible in the future.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8633
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8634
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8635
// Debugging support for CMSStackOverflowALot
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8636
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8637
// It's OK to call this multi-threaded;  the worst thing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8638
// that can happen is that we'll get a bunch of closely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8639
// spaced simulated oveflows, but that's OK, in fact
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8640
// probably good as it would exercise the overflow code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8641
// under contention.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8642
bool CMSCollector::simulate_overflow() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8643
  if (_overflow_counter-- <= 0) { // just being defensive
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8644
    _overflow_counter = CMSMarkStackOverflowInterval;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8645
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8646
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8647
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8648
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8649
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8650
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8651
bool CMSCollector::par_simulate_overflow() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8652
  return simulate_overflow();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8653
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8654
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8655
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8656
// Single-threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8657
bool CMSCollector::take_from_overflow_list(size_t num, CMSMarkStack* stack) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8658
  assert(stack->isEmpty(), "Expected precondition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8659
  assert(stack->capacity() > num, "Shouldn't bite more than can chew");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8660
  size_t i = num;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8661
  oop  cur = _overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8662
  const markOop proto = markOopDesc::prototype();
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8663
  NOT_PRODUCT(ssize_t n = 0;)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8664
  for (oop next; i > 0 && cur != NULL; cur = next, i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8665
    next = oop(cur->mark());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8666
    cur->set_mark(proto);   // until proven otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8667
    assert(cur->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8668
    bool res = stack->push(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8669
    assert(res, "Bit off more than can chew?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8670
    NOT_PRODUCT(n++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8671
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8672
  _overflow_list = cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8673
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8674
  assert(_num_par_pushes >= n, "Too many pops?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8675
  _num_par_pushes -=n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8676
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8677
  return !stack->isEmpty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8678
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8679
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8680
#define BUSY  (oop(0x1aff1aff))
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8681
// (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
  8682
// The overflow list is chained through the mark word of
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8683
// each object in the list. We fetch the entire list,
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8684
// break off a prefix of the right size and return the
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8685
// remainder. If other threads try to take objects from
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8686
// the overflow list at that time, they will wait for
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8687
// some time to see if data becomes available. If (and
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8688
// only if) another thread places one or more object(s)
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8689
// on the global list before we have returned the suffix
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8690
// to the global list, we will walk down our local list
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8691
// to find its end and append the global list to
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8692
// our suffix before returning it. This suffix walk can
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8693
// prove to be expensive (quadratic in the amount of traffic)
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8694
// when there are many objects in the overflow list and
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8695
// there is much producer-consumer contention on the list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8696
// *NOTE*: The overflow list manipulation code here and
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8697
// in ParNewGeneration:: are very similar in shape,
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8698
// 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
  8699
// 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
  8700
// Because of the common code, if you make any changes in
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8701
// the code below, please check the ParNew version to see if
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8702
// similar changes might be needed.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8703
// CR 6797058 has been filed to consolidate the common code.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8704
bool CMSCollector::par_take_from_overflow_list(size_t num,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8705
                                               OopTaskQueue* work_q) {
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8706
  assert(work_q->size() == 0, "First empty local work queue");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8707
  assert(num < work_q->max_elems(), "Can't bite more than we can chew");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8708
  if (_overflow_list == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8709
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8710
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8711
  // Grab the entire list; we'll put back a suffix
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8712
  oop prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8713
  Thread* tid = Thread::current();
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8714
  size_t CMSOverflowSpinCount = (size_t)ParallelGCThreads;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8715
  size_t sleep_time_millis = MAX2((size_t)1, num/100);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8716
  // If the list is busy, we spin for a short while,
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8717
  // sleeping between attempts to get the list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8718
  for (size_t spin = 0; prefix == BUSY && spin < CMSOverflowSpinCount; spin++) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8719
    os::sleep(tid, sleep_time_millis, false);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8720
    if (_overflow_list == NULL) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8721
      // Nothing left to take
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8722
      return false;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8723
    } else if (_overflow_list != BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8724
      // Try and grab the prefix
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8725
      prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8726
    }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8727
  }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8728
  // 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
  8729
  // enough, we give up and return empty-handed. If we leave
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8730
  // 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
  8731
  // some other thread holds the overflow list and will set it
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8732
  // to a non-BUSY state in the future.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8733
  if (prefix == NULL || prefix == BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8734
     // Nothing to take or waited long enough
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8735
     if (prefix == NULL) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8736
       // 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
  8737
       // and it is still the same value.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8738
       (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8739
     }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8740
     return false;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8741
  }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8742
  assert(prefix != NULL && prefix != BUSY, "Error");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8743
  size_t i = num;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8744
  oop cur = prefix;
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8745
  // Walk down the first "num" objects, unless we reach the end.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8746
  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
  8747
  if (cur->mark() == NULL) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8748
    // We have "num" or fewer elements in the list, so there
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8749
    // is nothing to return to the global list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8750
    // Write back the NULL in lieu of the BUSY we wrote
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8751
    // above, if it is still the same value.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8752
    if (_overflow_list == BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8753
      (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8754
    }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8755
  } else {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8756
    // Chop off the suffix and rerturn it to the global list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8757
    assert(cur->mark() != BUSY, "Error");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8758
    oop suffix_head = cur->mark(); // suffix will be put back on global list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8759
    cur->set_mark(NULL);           // break off suffix
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8760
    // 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
  8761
    // 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
  8762
    // able to place back the suffix without incurring the cost
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8763
    // of a walk down the list.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8764
    oop observed_overflow_list = _overflow_list;
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8765
    oop cur_overflow_list = observed_overflow_list;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8766
    bool attached = false;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8767
    while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8768
      observed_overflow_list =
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8769
        (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8770
      if (cur_overflow_list == observed_overflow_list) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8771
        attached = true;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8772
        break;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8773
      } else cur_overflow_list = observed_overflow_list;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8774
    }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8775
    if (!attached) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8776
      // 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
  8777
      // 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
  8778
      // list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8779
      for (cur = suffix_head; cur->mark() != NULL; cur = (oop)(cur->mark()));
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8780
      oop suffix_tail = cur;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8781
      assert(suffix_tail != NULL && suffix_tail->mark() == NULL,
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8782
             "Tautology");
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8783
      observed_overflow_list = _overflow_list;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8784
      do {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8785
        cur_overflow_list = observed_overflow_list;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8786
        if (cur_overflow_list != BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8787
          // Do the splice ...
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8788
          suffix_tail->set_mark(markOop(cur_overflow_list));
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8789
        } else { // cur_overflow_list == BUSY
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8790
          suffix_tail->set_mark(NULL);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8791
        }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8792
        // ... and try to place spliced list back on overflow_list ...
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8793
        observed_overflow_list =
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8794
          (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8795
      } while (cur_overflow_list != observed_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8796
      // ... until we have succeeded in doing so.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8797
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8798
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8799
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8800
  // Push the prefix elements on work_q
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8801
  assert(prefix != NULL, "control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8802
  const markOop proto = markOopDesc::prototype();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8803
  oop next;
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8804
  NOT_PRODUCT(ssize_t n = 0;)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8805
  for (cur = prefix; cur != NULL; cur = next) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8806
    next = oop(cur->mark());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8807
    cur->set_mark(proto);   // until proven otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8808
    assert(cur->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8809
    bool res = work_q->push(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8810
    assert(res, "Bit off more than we can chew?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8811
    NOT_PRODUCT(n++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8812
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8813
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8814
  assert(_num_par_pushes >= n, "Too many pops?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8815
  Atomic::add_ptr(-(intptr_t)n, &_num_par_pushes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8816
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8817
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8818
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8819
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8820
// Single-threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8821
void CMSCollector::push_on_overflow_list(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8822
  NOT_PRODUCT(_num_par_pushes++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8823
  assert(p->is_oop(), "Not an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8824
  preserve_mark_if_necessary(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8825
  p->set_mark((markOop)_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8826
  _overflow_list = p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8827
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8828
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8829
// Multi-threaded; use CAS to prepend to overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8830
void CMSCollector::par_push_on_overflow_list(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8831
  NOT_PRODUCT(Atomic::inc_ptr(&_num_par_pushes);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8832
  assert(p->is_oop(), "Not an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8833
  par_preserve_mark_if_necessary(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8834
  oop observed_overflow_list = _overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8835
  oop cur_overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8836
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8837
    cur_overflow_list = observed_overflow_list;
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8838
    if (cur_overflow_list != BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8839
      p->set_mark(markOop(cur_overflow_list));
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8840
    } else {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8841
      p->set_mark(NULL);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8842
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8843
    observed_overflow_list =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8844
      (oop) Atomic::cmpxchg_ptr(p, &_overflow_list, cur_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8845
  } while (cur_overflow_list != observed_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8846
}
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8847
#undef BUSY
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8848
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8849
// Single threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8850
// General Note on GrowableArray: pushes may silently fail
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8851
// because we are (temporarily) out of C-heap for expanding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8852
// the stack. The problem is quite ubiquitous and affects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8853
// a lot of code in the JVM. The prudent thing for GrowableArray
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8854
// to do (for now) is to exit with an error. However, that may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8855
// 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
  8856
// able to recover without much harm. For such cases, we
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8857
// should probably introduce a "soft_push" method which returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8858
// an indication of success or failure with the assumption that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8859
// the caller may be able to recover from a failure; code in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8860
// the VM can then be changed, incrementally, to deal with such
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8861
// failures where possible, thus, incrementally hardening the VM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8862
// in such low resource situations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8863
void CMSCollector::preserve_mark_work(oop p, markOop m) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8864
  if (_preserved_oop_stack == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8865
    assert(_preserved_mark_stack == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8866
           "bijection with preserved_oop_stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8867
    // Allocate the stacks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8868
    _preserved_oop_stack  = new (ResourceObj::C_HEAP)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8869
      GrowableArray<oop>(PreserveMarkStackSize, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8870
    _preserved_mark_stack = new (ResourceObj::C_HEAP)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8871
      GrowableArray<markOop>(PreserveMarkStackSize, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8872
    if (_preserved_oop_stack == NULL || _preserved_mark_stack == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8873
      vm_exit_out_of_memory(2* PreserveMarkStackSize * sizeof(oop) /* punt */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8874
                            "Preserved Mark/Oop Stack for CMS (C-heap)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8875
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8876
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8877
  _preserved_oop_stack->push(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8878
  _preserved_mark_stack->push(m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8879
  assert(m == p->mark(), "Mark word changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8880
  assert(_preserved_oop_stack->length() == _preserved_mark_stack->length(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8881
         "bijection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8882
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8883
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8884
// Single threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8885
void CMSCollector::preserve_mark_if_necessary(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8886
  markOop m = p->mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8887
  if (m->must_be_preserved(p)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8888
    preserve_mark_work(p, m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8889
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8890
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8891
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8892
void CMSCollector::par_preserve_mark_if_necessary(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8893
  markOop m = p->mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8894
  if (m->must_be_preserved(p)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8895
    MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8896
    // Even though we read the mark word without holding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8897
    // the lock, we are assured that it will not change
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8898
    // because we "own" this oop, so no other thread can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8899
    // be trying to push it on the overflow list; see
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8900
    // the assertion in preserve_mark_work() that checks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8901
    // that m == p->mark().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8902
    preserve_mark_work(p, m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8903
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8904
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8905
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8906
// We should be able to do this multi-threaded,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8907
// a chunk of stack being a task (this is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8908
// correct because each oop only ever appears
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8909
// once in the overflow list. However, it's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8910
// not very easy to completely overlap this with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8911
// other operations, so will generally not be done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8912
// until all work's been completed. Because we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8913
// expect the preserved oop stack (set) to be small,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8914
// it's probably fine to do this single-threaded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8915
// We can explore cleverer concurrent/overlapped/parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8916
// processing of preserved marks if we feel the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8917
// need for this in the future. Stack overflow should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8918
// be so rare in practice and, when it happens, its
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8919
// effect on performance so great that this will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8920
// likely just be in the noise anyway.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8921
void CMSCollector::restore_preserved_marks_if_any() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8922
  if (_preserved_oop_stack == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8923
    assert(_preserved_mark_stack == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8924
           "bijection with preserved_oop_stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8925
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8926
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8927
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8928
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8929
         "world should be stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8930
  assert(Thread::current()->is_ConcurrentGC_thread() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8931
         Thread::current()->is_VM_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8932
         "should be single-threaded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8933
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8934
  int length = _preserved_oop_stack->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8935
  assert(_preserved_mark_stack->length() == length, "bijection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8936
  for (int i = 0; i < length; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8937
    oop p = _preserved_oop_stack->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8938
    assert(p->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8939
    assert(_span.contains(p), "oop should be in _span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8940
    assert(p->mark() == markOopDesc::prototype(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8941
           "Set when taken from overflow list");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8942
    markOop m = _preserved_mark_stack->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8943
    p->set_mark(m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8944
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8945
  _preserved_mark_stack->clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8946
  _preserved_oop_stack->clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8947
  assert(_preserved_mark_stack->is_empty() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8948
         _preserved_oop_stack->is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8949
         "stacks were cleared above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8950
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8951
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8952
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8953
bool CMSCollector::no_preserved_marks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8954
  return (   (   _preserved_mark_stack == NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8955
              && _preserved_oop_stack == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8956
          || (   _preserved_mark_stack->is_empty()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8957
              && _preserved_oop_stack->is_empty()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8958
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8959
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8960
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8961
CMSAdaptiveSizePolicy* ASConcurrentMarkSweepGeneration::cms_size_policy() const
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8962
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8963
  GenCollectedHeap* gch = (GenCollectedHeap*) GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8964
  CMSAdaptiveSizePolicy* size_policy =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8965
    (CMSAdaptiveSizePolicy*) gch->gen_policy()->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8966
  assert(size_policy->is_gc_cms_adaptive_size_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8967
    "Wrong type for size policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8968
  return size_policy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8969
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8970
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8971
void ASConcurrentMarkSweepGeneration::resize(size_t cur_promo_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8972
                                           size_t desired_promo_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8973
  if (cur_promo_size < desired_promo_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8974
    size_t expand_bytes = desired_promo_size - cur_promo_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8975
    if (PrintAdaptiveSizePolicy && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8976
      gclog_or_tty->print_cr(" ASConcurrentMarkSweepGeneration::resize "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8977
        "Expanding tenured generation by " SIZE_FORMAT " (bytes)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8978
        expand_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8979
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8980
    expand(expand_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8981
           MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8982
           CMSExpansionCause::_adaptive_size_policy);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8983
  } else if (desired_promo_size < cur_promo_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8984
    size_t shrink_bytes = cur_promo_size - desired_promo_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8985
    if (PrintAdaptiveSizePolicy && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8986
      gclog_or_tty->print_cr(" ASConcurrentMarkSweepGeneration::resize "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8987
        "Shrinking tenured generation by " SIZE_FORMAT " (bytes)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8988
        shrink_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8989
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8990
    shrink(shrink_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8991
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8992
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8993
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8994
CMSGCAdaptivePolicyCounters* ASConcurrentMarkSweepGeneration::gc_adaptive_policy_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8995
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8996
  CMSGCAdaptivePolicyCounters* counters =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8997
    (CMSGCAdaptivePolicyCounters*) gch->collector_policy()->counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8998
  assert(counters->kind() == GCPolicyCounters::CMSGCAdaptivePolicyCountersKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8999
    "Wrong kind of counters");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9000
  return counters;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9001
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9003
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9004
void ASConcurrentMarkSweepGeneration::update_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9005
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9006
    _space_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9007
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9008
    CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9009
    GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9010
    CMSGCStats* gc_stats_l = (CMSGCStats*) gc_stats();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9011
    assert(gc_stats_l->kind() == GCStats::CMSGCStatsKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9012
      "Wrong gc statistics type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9013
    counters->update_counters(gc_stats_l);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9014
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9015
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9016
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9017
void ASConcurrentMarkSweepGeneration::update_counters(size_t used) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9018
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9019
    _space_counters->update_used(used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9020
    _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9021
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9022
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9023
    CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9024
    GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9025
    CMSGCStats* gc_stats_l = (CMSGCStats*) gc_stats();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9026
    assert(gc_stats_l->kind() == GCStats::CMSGCStatsKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9027
      "Wrong gc statistics type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9028
    counters->update_counters(gc_stats_l);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9029
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9030
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9031
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9032
// The desired expansion delta is computed so that:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9033
// . desired free percentage or greater is used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9034
void ASConcurrentMarkSweepGeneration::compute_new_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9035
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9036
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9037
  GenCollectedHeap* gch = (GenCollectedHeap*) GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9038
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9039
  // If incremental collection failed, we just want to expand
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9040
  // to the limit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9041
  if (incremental_collection_failed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9042
    clear_incremental_collection_failed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9043
    grow_to_reserved();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9044
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9045
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9046
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9047
  assert(UseAdaptiveSizePolicy, "Should be using adaptive sizing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9048
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9049
  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9050
    "Wrong type of heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9051
  int prev_level = level() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9052
  assert(prev_level >= 0, "The cms generation is the lowest generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9053
  Generation* prev_gen = gch->get_gen(prev_level);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9054
  assert(prev_gen->kind() == Generation::ASParNew,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9055
    "Wrong type of young generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9056
  ParNewGeneration* younger_gen = (ParNewGeneration*) prev_gen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9057
  size_t cur_eden = younger_gen->eden()->capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9058
  CMSAdaptiveSizePolicy* size_policy = cms_size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9059
  size_t cur_promo = free();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9060
  size_policy->compute_tenured_generation_free_space(cur_promo,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9061
                                                       max_available(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9062
                                                       cur_eden);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9063
  resize(cur_promo, size_policy->promo_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9064
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9065
  // Record the new size of the space in the cms generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9066
  // that is available for promotions.  This is temporary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9067
  // It should be the desired promo size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9068
  size_policy->avg_cms_promo()->sample(free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9069
  size_policy->avg_old_live()->sample(used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9070
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9071
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9072
    CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9073
    counters->update_cms_capacity_counter(capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9074
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9075
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9076
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9077
void ASConcurrentMarkSweepGeneration::shrink_by(size_t desired_bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9078
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9079
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9080
  HeapWord* old_end = _cmsSpace->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9081
  HeapWord* unallocated_start = _cmsSpace->unallocated_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9082
  assert(old_end >= unallocated_start, "Miscalculation of unallocated_start");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9083
  FreeChunk* chunk_at_end = find_chunk_at_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9084
  if (chunk_at_end == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9085
    // No room to shrink
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9086
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9087
      gclog_or_tty->print_cr("No room to shrink: old_end  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9088
        PTR_FORMAT "  unallocated_start  " PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9089
        " chunk_at_end  " PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9090
        old_end, unallocated_start, chunk_at_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9091
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9092
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9093
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9094
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9095
    // Find the chunk at the end of the space and determine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9096
    // how much it can be shrunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9097
    size_t shrinkable_size_in_bytes = chunk_at_end->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9098
    size_t aligned_shrinkable_size_in_bytes =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9099
      align_size_down(shrinkable_size_in_bytes, os::vm_page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9100
    assert(unallocated_start <= chunk_at_end->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9101
      "Inconsistent chunk at end of space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9102
    size_t bytes = MIN2(desired_bytes, aligned_shrinkable_size_in_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9103
    size_t word_size_before = heap_word_size(_virtual_space.committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9105
    // Shrink the underlying space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9106
    _virtual_space.shrink_by(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9107
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9108
      gclog_or_tty->print_cr("ConcurrentMarkSweepGeneration::shrink_by:"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9109
        " desired_bytes " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9110
        " shrinkable_size_in_bytes " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9111
        " aligned_shrinkable_size_in_bytes " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9112
        "  bytes  " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9113
        desired_bytes, shrinkable_size_in_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9114
        aligned_shrinkable_size_in_bytes, bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9115
      gclog_or_tty->print_cr("          old_end  " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9116
        "  unallocated_start  " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9117
        old_end, unallocated_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9118
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9119
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9120
    // If the space did shrink (shrinking is not guaranteed),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9121
    // shrink the chunk at the end by the appropriate amount.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9122
    if (((HeapWord*)_virtual_space.high()) < old_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9123
      size_t new_word_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9124
        heap_word_size(_virtual_space.committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9125
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9126
      // Have to remove the chunk from the dictionary because it is changing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9127
      // size and might be someplace elsewhere in the dictionary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9128
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9129
      // Get the chunk at end, shrink it, and put it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9130
      // back.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9131
      _cmsSpace->removeChunkFromDictionary(chunk_at_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9132
      size_t word_size_change = word_size_before - new_word_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9133
      size_t chunk_at_end_old_size = chunk_at_end->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9134
      assert(chunk_at_end_old_size >= word_size_change,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9135
        "Shrink is too large");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9136
      chunk_at_end->setSize(chunk_at_end_old_size -
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9137
                          word_size_change);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9138
      _cmsSpace->freed((HeapWord*) chunk_at_end->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9139
        word_size_change);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9140
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9141
      _cmsSpace->returnChunkToDictionary(chunk_at_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9142
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9143
      MemRegion mr(_cmsSpace->bottom(), new_word_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9144
      _bts->resize(new_word_size);  // resize the block offset shared array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9145
      Universe::heap()->barrier_set()->resize_covered_region(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9146
      _cmsSpace->assert_locked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9147
      _cmsSpace->set_end((HeapWord*)_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9148
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9149
      NOT_PRODUCT(_cmsSpace->dictionary()->verify());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9150
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9151
      // update the space and generation capacity counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9152
      if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9153
        _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9154
        _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9155
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9156
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9157
      if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9158
        size_t new_mem_size = _virtual_space.committed_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9159
        size_t old_mem_size = new_mem_size + bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9160
        gclog_or_tty->print_cr("Shrinking %s from %ldK by %ldK to %ldK",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9161
                      name(), old_mem_size/K, bytes/K, new_mem_size/K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9162
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9163
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9164
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9165
    assert(_cmsSpace->unallocated_block() <= _cmsSpace->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9166
      "Inconsistency at end of space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9167
    assert(chunk_at_end->end() == _cmsSpace->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9168
      "Shrinking is inconsistent");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9169
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9170
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9171
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9172
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9173
// Transfer some number of overflown objects to usual marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9174
// stack. Return true if some objects were transferred.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9175
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
  9176
  size_t num = MIN2((size_t)(_mark_stack->capacity() - _mark_stack->length())/4,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9177
                    (size_t)ParGCDesiredObjsFromOverflowList);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9179
  bool res = _collector->take_from_overflow_list(num, _mark_stack);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9180
  assert(_collector->overflow_list_is_empty() || res,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9181
         "If list is not empty, we should have taken something");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9182
  assert(!res || !_mark_stack->isEmpty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9183
         "If we took something, it should now be on our stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9184
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9185
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9186
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9187
size_t MarkDeadObjectsClosure::do_blk(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9188
  size_t res = _sp->block_size_no_stall(addr, _collector);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9189
  assert(res != 0, "Should always be able to compute a size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9190
  if (_sp->block_is_obj(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9191
    if (_live_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9192
      // It can't have been dead in a previous cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9193
      guarantee(!_dead_bit_map->isMarked(addr), "No resurrection!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9194
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9195
      _dead_bit_map->mark(addr);      // mark the dead object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9196
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9197
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9198
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9199
}
6245
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9200
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9201
TraceCMSMemoryManagerStats::TraceCMSMemoryManagerStats(CMSCollector::CollectorState phase): TraceMemoryManagerStats() {
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9202
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9203
  switch (phase) {
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9204
    case CMSCollector::InitialMarking:
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9205
      initialize(true  /* fullGC */ ,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9206
                 true  /* recordGCBeginTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9207
                 true  /* recordPreGCUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9208
                 false /* recordPeakUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9209
                 false /* recordPostGCusage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9210
                 true  /* recordAccumulatedGCTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9211
                 false /* recordGCEndTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9212
                 false /* countCollection */  );
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9213
      break;
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9214
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9215
    case CMSCollector::FinalMarking:
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9216
      initialize(true  /* fullGC */ ,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9217
                 false /* recordGCBeginTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9218
                 false /* recordPreGCUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9219
                 false /* recordPeakUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9220
                 false /* recordPostGCusage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9221
                 true  /* recordAccumulatedGCTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9222
                 false /* recordGCEndTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9223
                 false /* countCollection */  );
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9224
      break;
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9225
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9226
    case CMSCollector::Sweeping:
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9227
      initialize(true  /* fullGC */ ,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9228
                 false /* recordGCBeginTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9229
                 false /* recordPreGCUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9230
                 true  /* recordPeakUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9231
                 true  /* recordPostGCusage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9232
                 false /* recordAccumulatedGCTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9233
                 true  /* recordGCEndTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9234
                 true  /* countCollection */  );
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9235
      break;
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9236
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9237
    default:
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9238
      ShouldNotReachHere();
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9239
  }
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9240
}
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9241
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9242
// when bailing out of cms in concurrent mode failure
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9243
TraceCMSMemoryManagerStats::TraceCMSMemoryManagerStats(): TraceMemoryManagerStats() {
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9244
  initialize(true /* fullGC */ ,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9245
             true /* recordGCBeginTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9246
             true /* recordPreGCUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9247
             true /* recordPeakUsage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9248
             true /* recordPostGCusage */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9249
             true /* recordAccumulatedGCTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9250
             true /* recordGCEndTime */,
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9251
             true /* countCollection */ );
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9252
}
c37d2cf6de1a 6581734: CMS Old Gen's collection usage is zero after GC which is incorrect
kevinw
parents: 5702
diff changeset
  9253