hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
author ysr
Thu, 20 Nov 2008 16:56:09 -0800
changeset 1606 dcf9714addbe
parent 1605 6b43d186eb8d
child 1610 5dddd195cc86
permissions -rw-r--r--
6684579: SoftReference processing can be made more efficient Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not. Reviewed-by: jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
670
ddf3e9583f2f 6719955: Update copyright year
xdono
parents: 613
diff changeset
     2
 * Copyright 2001-2008 Sun Microsystems, Inc.  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
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
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),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  _dilatation_factor(((double)MinChunkSize)/((double)(oopDesc::header_size()))),
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.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  assert(MinChunkSize >= oopDesc::header_size(), "just checking");
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
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   256
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
void ConcurrentMarkSweepGeneration::ref_processor_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  assert(collector() != NULL, "no collector");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  collector()->ref_processor_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
void CMSCollector::ref_processor_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  if (_ref_processor == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
    // Allocate and initialize a reference processor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
    _ref_processor = ReferenceProcessor::create_ref_processor(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
        _span,                               // span
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
        _cmsGen->refs_discovery_is_atomic(), // atomic_discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
        _cmsGen->refs_discovery_is_mt(),     // mt_discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
        &_is_alive_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
        ParallelGCThreads,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
        ParallelRefProcEnabled);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
    // Initialize the _ref_processor field of CMSGen
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
    _cmsGen->set_ref_processor(_ref_processor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
    // Allocate a dummy ref processor for perm gen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
    ReferenceProcessor* rp2 = new ReferenceProcessor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
    if (rp2 == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
      vm_exit_during_initialization("Could not allocate ReferenceProcessor object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
    _permGen->set_ref_processor(rp2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
CMSAdaptiveSizePolicy* CMSCollector::size_policy() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
    "Wrong type of heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  CMSAdaptiveSizePolicy* sp = (CMSAdaptiveSizePolicy*)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
    gch->gen_policy()->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  assert(sp->is_gc_cms_adaptive_size_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
    "Wrong type of size policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  return sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
CMSGCAdaptivePolicyCounters* CMSCollector::gc_adaptive_policy_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  CMSGCAdaptivePolicyCounters* results =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
    (CMSGCAdaptivePolicyCounters*) collector_policy()->counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
  assert(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    results->kind() == GCPolicyCounters::CMSGCAdaptivePolicyCountersKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
    "Wrong gc policy counter kind");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
  return results;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
void ConcurrentMarkSweepGeneration::initialize_performance_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
  const char* gen_name = "old";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
  // Generation Counters - generation 1, 1 subspace
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  _gen_counters = new GenerationCounters(gen_name, 1, 1, &_virtual_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  _space_counters = new GSpaceCounters(gen_name, 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
                                       _virtual_space.reserved_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
                                       this, _gen_counters);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
CMSStats::CMSStats(ConcurrentMarkSweepGeneration* cms_gen, unsigned int alpha):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  _cms_gen(cms_gen)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  assert(alpha <= 100, "bad value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
  _saved_alpha = alpha;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
  // Initialize the alphas to the bootstrap value of 100.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  _gc0_alpha = _cms_alpha = 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  _cms_begin_time.update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  _cms_end_time.update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  _gc0_duration = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  _gc0_period = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  _gc0_promoted = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  _cms_duration = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  _cms_period = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  _cms_allocated = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  _cms_used_at_gc0_begin = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
  _cms_used_at_gc0_end = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  _allow_duty_cycle_reduction = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  _valid_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  _icms_duty_cycle = CMSIncrementalDutyCycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
// If promotion failure handling is on use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
// the padded average size of the promotion for each
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
// young generation collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
double CMSStats::time_until_cms_gen_full() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
  size_t cms_free = _cms_gen->cmsSpace()->free();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  size_t expected_promotion = gch->get_gen(0)->capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
  if (HandlePromotionFailure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
    expected_promotion = MIN2(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
        (size_t) _cms_gen->gc_stats()->avg_promoted()->padded_average(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
        expected_promotion);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  if (cms_free > expected_promotion) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
    // Start a cms collection if there isn't enough space to promote
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
    // for the next minor collection.  Use the padded average as
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
    // a safety factor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
    cms_free -= expected_promotion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
    // Adjust by the safety factor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
    double cms_free_dbl = (double)cms_free;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
    cms_free_dbl = cms_free_dbl * (100.0 - CMSIncrementalSafetyFactor) / 100.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
      gclog_or_tty->print_cr("CMSStats::time_until_cms_gen_full: cms_free "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
        SIZE_FORMAT " expected_promotion " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
        cms_free, expected_promotion);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
      gclog_or_tty->print_cr("  cms_free_dbl %f cms_consumption_rate %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
        cms_free_dbl, cms_consumption_rate() + 1.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
    // Add 1 in case the consumption rate goes to zero.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
    return cms_free_dbl / (cms_consumption_rate() + 1.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  return 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
// Compare the duration of the cms collection to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
// time remaining before the cms generation is empty.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
// Note that the time from the start of the cms collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
// to the start of the cms sweep (less than the total
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
// duration of the cms collection) can be used.  This
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
// has been tried and some applications experienced
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
// promotion failures early in execution.  This was
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
// possibly because the averages were not accurate
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
// enough at the beginning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
double CMSStats::time_until_cms_start() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  // We add "gc0_period" to the "work" calculation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
  // below because this query is done (mostly) at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  // end of a scavenge, so we need to conservatively
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  // account for that much possible delay
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  // in the query so as to avoid concurrent mode failures
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  // due to starting the collection just a wee bit too
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  // late.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
  double work = cms_duration() + gc0_period();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  double deadline = time_until_cms_gen_full();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  if (work > deadline) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
      gclog_or_tty->print(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
        " CMSCollector: collect because of anticipated promotion "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
        "before full %3.7f + %3.7f > %3.7f ", cms_duration(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
        gc0_period(), time_until_cms_gen_full());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
    return 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  return work - deadline;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
// Return a duty cycle based on old_duty_cycle and new_duty_cycle, limiting the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
// amount of change to prevent wild oscillation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
unsigned int CMSStats::icms_damped_duty_cycle(unsigned int old_duty_cycle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
                                              unsigned int new_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  assert(old_duty_cycle <= 100, "bad input value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  assert(new_duty_cycle <= 100, "bad input value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  // Note:  use subtraction with caution since it may underflow (values are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  // unsigned).  Addition is safe since we're in the range 0-100.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  unsigned int damped_duty_cycle = new_duty_cycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  if (new_duty_cycle < old_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
    const unsigned int largest_delta = MAX2(old_duty_cycle / 4, 5U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
    if (new_duty_cycle + largest_delta < old_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
      damped_duty_cycle = old_duty_cycle - largest_delta;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  } else if (new_duty_cycle > old_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
    const unsigned int largest_delta = MAX2(old_duty_cycle / 4, 15U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
    if (new_duty_cycle > old_duty_cycle + largest_delta) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
      damped_duty_cycle = MIN2(old_duty_cycle + largest_delta, 100U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  assert(damped_duty_cycle <= 100, "invalid duty cycle computed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  if (CMSTraceIncrementalPacing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
    gclog_or_tty->print(" [icms_damped_duty_cycle(%d,%d) = %d] ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
                           old_duty_cycle, new_duty_cycle, damped_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
  return damped_duty_cycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
unsigned int CMSStats::icms_update_duty_cycle_impl() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
  assert(CMSIncrementalPacing && valid(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
         "should be handled in icms_update_duty_cycle()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  double cms_time_so_far = cms_timer().seconds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  double scaled_duration = cms_duration_per_mb() * _cms_used_at_gc0_end / M;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
  double scaled_duration_remaining = fabsd(scaled_duration - cms_time_so_far);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
  // Avoid division by 0.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  double time_until_full = MAX2(time_until_cms_gen_full(), 0.01);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  double duty_cycle_dbl = 100.0 * scaled_duration_remaining / time_until_full;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
  unsigned int new_duty_cycle = MIN2((unsigned int)duty_cycle_dbl, 100U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  if (new_duty_cycle > _icms_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
    // Avoid very small duty cycles (1 or 2); 0 is allowed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
    if (new_duty_cycle > 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
      _icms_duty_cycle = icms_damped_duty_cycle(_icms_duty_cycle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
                                                new_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  } else if (_allow_duty_cycle_reduction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
    // The duty cycle is reduced only once per cms cycle (see record_cms_end()).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
    new_duty_cycle = icms_damped_duty_cycle(_icms_duty_cycle, new_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
    // Respect the minimum duty cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
    unsigned int min_duty_cycle = (unsigned int)CMSIncrementalDutyCycleMin;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
    _icms_duty_cycle = MAX2(new_duty_cycle, min_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  if (PrintGCDetails || CMSTraceIncrementalPacing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
    gclog_or_tty->print(" icms_dc=%d ", _icms_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  _allow_duty_cycle_reduction = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  return _icms_duty_cycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
void CMSStats::print_on(outputStream *st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
  st->print(" gc0_alpha=%d,cms_alpha=%d", _gc0_alpha, _cms_alpha);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  st->print(",gc0_dur=%g,gc0_per=%g,gc0_promo=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
               gc0_duration(), gc0_period(), gc0_promoted());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
  st->print(",cms_dur=%g,cms_dur_per_mb=%g,cms_per=%g,cms_alloc=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
            cms_duration(), cms_duration_per_mb(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
            cms_period(), cms_allocated());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  st->print(",cms_since_beg=%g,cms_since_end=%g",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
            cms_time_since_begin(), cms_time_since_end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
  st->print(",cms_used_beg=" SIZE_FORMAT ",cms_used_end=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
            _cms_used_at_gc0_begin, _cms_used_at_gc0_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
  if (CMSIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
    st->print(",dc=%d", icms_duty_cycle());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  if (valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
    st->print(",promo_rate=%g,cms_alloc_rate=%g",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
              promotion_rate(), cms_allocation_rate());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
    st->print(",cms_consumption_rate=%g,time_until_full=%g",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
              cms_consumption_rate(), time_until_cms_gen_full());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
  st->print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
#endif // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
CMSCollector::CollectorState CMSCollector::_collectorState =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
                             CMSCollector::Idling;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
bool CMSCollector::_foregroundGCIsActive = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
bool CMSCollector::_foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
                           ConcurrentMarkSweepGeneration* permGen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
                           CardTableRS*                   ct,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
                           ConcurrentMarkSweepPolicy*     cp):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  _cmsGen(cmsGen),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  _permGen(permGen),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  _ct(ct),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  _ref_processor(NULL),    // will be set later
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  _conc_workers(NULL),     // may be set later
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  _abort_preclean(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  _start_sampling(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  _between_prologue_and_epilogue(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  _markBitMap(0, Mutex::leaf + 1, "CMS_markBitMap_lock"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  _perm_gen_verify_bit_map(0, -1 /* no mutex */, "No_lock"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  _modUnionTable((CardTableModRefBS::card_shift - LogHeapWordSize),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
                 -1 /* lock-free */, "No_lock" /* dummy */),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  _modUnionClosure(&_modUnionTable),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  _modUnionClosurePar(&_modUnionTable),
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   524
  // 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
   525
  _span(cmsGen->reserved()._union(permGen->reserved())),
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   526
  // Construct the is_alive_closure with _span & markBitMap
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   527
  _is_alive_closure(_span, &_markBitMap),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  _restart_addr(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  _overflow_list(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  _preserved_oop_stack(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  _preserved_mark_stack(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  _stats(cmsGen),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  _eden_chunk_array(NULL),     // may be set in ctor body
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
  _eden_chunk_capacity(0),     // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
  _eden_chunk_index(0),        // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  _survivor_plab_array(NULL),  // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
  _survivor_chunk_array(NULL), // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
  _survivor_chunk_capacity(0), // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
  _survivor_chunk_index(0),    // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
  _ser_pmc_preclean_ovflw(0),
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
   541
  _ser_kac_preclean_ovflw(0),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
  _ser_pmc_remark_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
  _par_pmc_remark_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
  _ser_kac_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
  _par_kac_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  _num_par_pushes(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
  _collection_count_start(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
  _verifying(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
  _icms_start_limit(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  _icms_stop_limit(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
  _verification_mark_bm(0, Mutex::leaf + 1, "CMS_verification_mark_bm_lock"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
  _completed_initialization(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  _collector_policy(cp),
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   556
  _should_unload_classes(false),
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   557
  _concurrent_cycles_since_last_unload(0),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
  _sweep_estimate(CMS_SweepWeight, CMS_SweepPadding)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  if (ExplicitGCInvokesConcurrentAndUnloadsClasses) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
    ExplicitGCInvokesConcurrent = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
  // Now expand the span and allocate the collection support structures
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
  // (MUT, marking bit map etc.) to cover both generations subject to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  // collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  // First check that _permGen is adjacent to _cmsGen and above it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  assert(   _cmsGen->reserved().word_size()  > 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
         && _permGen->reserved().word_size() > 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
         "generations should not be of zero size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
  assert(_cmsGen->reserved().intersection(_permGen->reserved()).is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
         "_cmsGen and _permGen should not overlap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
  assert(_cmsGen->reserved().end() == _permGen->reserved().start(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
         "_cmsGen->end() different from _permGen->start()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
  // For use by dirty card to oop closures.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
  _cmsGen->cmsSpace()->set_collector(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  _permGen->cmsSpace()->set_collector(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  // Allocate MUT and marking bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
    MutexLockerEx x(_markBitMap.lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
    if (!_markBitMap.allocate(_span)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
      warning("Failed to allocate CMS Bit Map");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
    assert(_markBitMap.covers(_span), "_markBitMap inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
    _modUnionTable.allocate(_span);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
    assert(_modUnionTable.covers(_span), "_modUnionTable inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
  if (!_markStack.allocate(CMSMarkStackSize)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
    warning("Failed to allocate CMS Marking Stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
  if (!_revisitStack.allocate(CMSRevisitStackSize)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
    warning("Failed to allocate CMS Revisit Stack");
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
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  // Support for multi-threaded concurrent phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  if (ParallelGCThreads > 0 && CMSConcurrentMTEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
    if (FLAG_IS_DEFAULT(ParallelCMSThreads)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
      // just for now
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
      FLAG_SET_DEFAULT(ParallelCMSThreads, (ParallelGCThreads + 3)/4);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
    if (ParallelCMSThreads > 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
      _conc_workers = new YieldingFlexibleWorkGang("Parallel CMS Threads",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
                                 ParallelCMSThreads, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
      if (_conc_workers == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
        warning("GC/CMS: _conc_workers allocation failure: "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
              "forcing -CMSConcurrentMTEnabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
        CMSConcurrentMTEnabled = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
      CMSConcurrentMTEnabled = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
  if (!CMSConcurrentMTEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
    ParallelCMSThreads = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
    // Turn off CMSCleanOnEnter optimization temporarily for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
    // the MT case where it's not fixed yet; see 6178663.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
    CMSCleanOnEnter = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
  assert((_conc_workers != NULL) == (ParallelCMSThreads > 1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
         "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
  // Parallel task queues; these are shared for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
  // concurrent and stop-world phases of CMS, but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
  // are not shared with parallel scavenge (ParNew).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
    uint i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
    uint num_queues = (uint) MAX2(ParallelGCThreads, ParallelCMSThreads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
    if ((CMSParallelRemarkEnabled || CMSConcurrentMTEnabled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
         || ParallelRefProcEnabled)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
        && num_queues > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
      _task_queues = new OopTaskQueueSet(num_queues);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
      if (_task_queues == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
        warning("task_queues allocation failure.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
      _hash_seed = NEW_C_HEAP_ARRAY(int, num_queues);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
      if (_hash_seed == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
        warning("_hash_seed array allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
      // XXX use a global constant instead of 64!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
      typedef struct OopTaskQueuePadded {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
        OopTaskQueue work_queue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
        char pad[64 - sizeof(OopTaskQueue)];  // prevent false sharing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
      } OopTaskQueuePadded;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
      for (i = 0; i < num_queues; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
        OopTaskQueuePadded *q_padded = new OopTaskQueuePadded();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
        if (q_padded == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
          warning("work_queue allocation failure.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
        _task_queues->register_queue(i, &q_padded->work_queue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
      for (i = 0; i < num_queues; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
        _task_queues->queue(i)->initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
        _hash_seed[i] = 17;  // copied from ParNew
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   673
  _cmsGen ->init_initiating_occupancy(CMSInitiatingOccupancyFraction, CMSTriggerRatio);
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   674
  _permGen->init_initiating_occupancy(CMSInitiatingPermOccupancyFraction, CMSTriggerPermRatio);
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   675
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
  // Clip CMSBootstrapOccupancy between 0 and 100.
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   677
  _bootstrap_occupancy = ((double)MIN2((uintx)100, MAX2((uintx)0, CMSBootstrapOccupancy)))
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
                         /(double)100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
  _full_gcs_since_conc_gc = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
  // Now tell CMS generations the identity of their collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
  ConcurrentMarkSweepGeneration::set_collector(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
  // Create & start a CMS thread for this CMS collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
  _cmsThread = ConcurrentMarkSweepThread::start(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
  assert(cmsThread() != NULL, "CMS Thread should have been created");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
  assert(cmsThread()->collector() == this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
         "CMS Thread should refer to this gen");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
  assert(CGC_lock != NULL, "Where's the CGC_lock?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
  // Support for parallelizing young gen rescan
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
  _young_gen = gch->prev_gen(_cmsGen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
  if (gch->supports_inline_contig_alloc()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
    _top_addr = gch->top_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
    _end_addr = gch->end_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
    assert(_young_gen != NULL, "no _young_gen");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
    _eden_chunk_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
    _eden_chunk_capacity = (_young_gen->max_capacity()+CMSSamplingGrain)/CMSSamplingGrain;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
    _eden_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, _eden_chunk_capacity);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
    if (_eden_chunk_array == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
      _eden_chunk_capacity = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
      warning("GC/CMS: _eden_chunk_array allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
  assert(_eden_chunk_array != NULL || _eden_chunk_capacity == 0, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
  // Support for parallelizing survivor space rescan
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
  if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
    size_t max_plab_samples = MaxNewSize/((SurvivorRatio+2)*MinTLABSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
    _survivor_plab_array  = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
    _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
    _cursor               = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
    if (_survivor_plab_array == NULL || _survivor_chunk_array == NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
        || _cursor == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
      warning("Failed to allocate survivor plab/chunk array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
      if (_survivor_plab_array  != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
        FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
        _survivor_plab_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
      if (_survivor_chunk_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
        FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
        _survivor_chunk_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
      if (_cursor != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
        FREE_C_HEAP_ARRAY(size_t, _cursor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
        _cursor = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
      _survivor_chunk_capacity = 2*max_plab_samples;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
      for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
        HeapWord** vec = NEW_C_HEAP_ARRAY(HeapWord*, max_plab_samples);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
        if (vec == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
          warning("Failed to allocate survivor plab array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
          for (int j = i; j > 0; j--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
            FREE_C_HEAP_ARRAY(HeapWord*, _survivor_plab_array[j-1].array());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
          FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
          FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
          _survivor_plab_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
          _survivor_chunk_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
          _survivor_chunk_capacity = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
          ChunkArray* cur =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
            ::new (&_survivor_plab_array[i]) ChunkArray(vec,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
                                                        max_plab_samples);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
          assert(cur->end() == 0, "Should be 0");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
          assert(cur->array() == vec, "Should be vec");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
          assert(cur->capacity() == max_plab_samples, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
  assert(   (   _survivor_plab_array  != NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
             && _survivor_chunk_array != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
         || (   _survivor_chunk_capacity == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
             && _survivor_chunk_index == 0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
         "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
  // Choose what strong roots should be scanned depending on verification options
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
  // and perm gen collection mode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
  if (!CMSClassUnloadingEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
    // If class unloading is disabled we want to include all classes into the root set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
    add_root_scanning_option(SharedHeap::SO_AllClasses);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
    add_root_scanning_option(SharedHeap::SO_SystemClasses);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
  NOT_PRODUCT(_overflow_counter = CMSMarkStackOverflowInterval;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
  _gc_counters = new CollectorCounters("CMS", 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
  _completed_initialization = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
  _sweep_timer.start();  // start of time
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
const char* ConcurrentMarkSweepGeneration::name() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
  return "concurrent mark-sweep generation";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
void ConcurrentMarkSweepGeneration::update_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
    _space_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
// this is an optimized version of update_counters(). it takes the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
// used value as a parameter rather than computing it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
void ConcurrentMarkSweepGeneration::update_counters(size_t used) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
    _space_counters->update_used(used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
    _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
void ConcurrentMarkSweepGeneration::print() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
  Generation::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
  cmsSpace()->print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
void ConcurrentMarkSweepGeneration::print_statistics() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
  cmsSpace()->printFLCensus(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
void ConcurrentMarkSweepGeneration::printOccupancy(const char *s) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
  if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
    if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
      gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
        level(), short_name(), s, used(), capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
      gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
        level(), short_name(), s, used() / K, capacity() / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
  if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
    gclog_or_tty->print(" "SIZE_FORMAT"("SIZE_FORMAT")",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
              gch->used(), gch->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
    gclog_or_tty->print(" "SIZE_FORMAT"K("SIZE_FORMAT"K)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
              gch->used() / K, gch->capacity() / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
size_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
ConcurrentMarkSweepGeneration::contiguous_available() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
  // dld proposes an improvement in precision here. If the committed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
  // part of the space ends in a free block we should add that to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
  // uncommitted size in the calculation below. Will make this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
  // change later, staying with the approximation below for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
  // time being. -- ysr.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
  return MAX2(_virtual_space.uncommitted_size(), unsafe_max_alloc_nogc());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
size_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
ConcurrentMarkSweepGeneration::unsafe_max_alloc_nogc() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
  return _cmsSpace->max_alloc_in_words() * HeapWordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
size_t ConcurrentMarkSweepGeneration::max_available() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
  return free() + _virtual_space.uncommitted_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
bool ConcurrentMarkSweepGeneration::promotion_attempt_is_safe(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
    size_t max_promotion_in_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
    bool younger_handles_promotion_failure) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
  // This is the most conservative test.  Full promotion is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
  // guaranteed if this is used. The multiplicative factor is to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
  // account for the worst case "dilatation".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
  double adjusted_max_promo_bytes = _dilatation_factor * max_promotion_in_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
  if (adjusted_max_promo_bytes > (double)max_uintx) { // larger than size_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
    adjusted_max_promo_bytes = (double)max_uintx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
  bool result = (max_contiguous_available() >= (size_t)adjusted_max_promo_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
  if (younger_handles_promotion_failure && !result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
    // Full promotion is not guaranteed because fragmentation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
    // of the cms generation can prevent the full promotion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
    result = (max_available() >= (size_t)adjusted_max_promo_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
    if (!result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
      // With promotion failure handling the test for the ability
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
      // to support the promotion does not have to be guaranteed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
      // Use an average of the amount promoted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
      result = max_available() >= (size_t)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
        gc_stats()->avg_promoted()->padded_average();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
      if (PrintGC && Verbose && result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
        gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
          "\nConcurrentMarkSweepGeneration::promotion_attempt_is_safe"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
          " max_available: " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
          " avg_promoted: " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
          max_available(), (size_t)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
          gc_stats()->avg_promoted()->padded_average());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
      if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
        gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
          "\nConcurrentMarkSweepGeneration::promotion_attempt_is_safe"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
          " max_available: " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
          " adj_max_promo_bytes: " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
          max_available(), (size_t)adjusted_max_promo_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
    if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
      gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
        "\nConcurrentMarkSweepGeneration::promotion_attempt_is_safe"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
        " contiguous_available: " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
        " adj_max_promo_bytes: " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
        max_contiguous_available(), (size_t)adjusted_max_promo_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
CompactibleSpace*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
ConcurrentMarkSweepGeneration::first_compaction_space() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
  return _cmsSpace;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
void ConcurrentMarkSweepGeneration::reset_after_compaction() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
  // Clear the promotion information.  These pointers can be adjusted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
  // along with all the other pointers into the heap but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
  // compaction is expected to be a rare event with
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
  // a heap using cms so don't do it without seeing the need.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
  if (ParallelGCThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
    for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
      _par_gc_thread_states[i]->promo.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
void ConcurrentMarkSweepGeneration::space_iterate(SpaceClosure* blk, bool usedOnly) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
  blk->do_space(_cmsSpace);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
void ConcurrentMarkSweepGeneration::compute_new_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
  // If incremental collection failed, we just want to expand
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
  // to the limit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
  if (incremental_collection_failed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
    clear_incremental_collection_failed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
    grow_to_reserved();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
  size_t expand_bytes = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
  double free_percentage = ((double) free()) / capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
  double desired_free_percentage = (double) MinHeapFreeRatio / 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
  double maximum_free_percentage = (double) MaxHeapFreeRatio / 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
  // compute expansion delta needed for reaching desired free percentage
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
  if (free_percentage < desired_free_percentage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
    size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
    assert(desired_capacity >= capacity(), "invalid expansion size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
    expand_bytes = MAX2(desired_capacity - capacity(), MinHeapDeltaBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
  if (expand_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
      size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
      gclog_or_tty->print_cr("\nFrom compute_new_size: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
      gclog_or_tty->print_cr("  Free fraction %f", free_percentage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
      gclog_or_tty->print_cr("  Desired free fraction %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
        desired_free_percentage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
      gclog_or_tty->print_cr("  Maximum free fraction %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
        maximum_free_percentage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
      gclog_or_tty->print_cr("  Capactiy "SIZE_FORMAT, capacity()/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
      gclog_or_tty->print_cr("  Desired capacity "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
        desired_capacity/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
      int prev_level = level() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
      if (prev_level >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
        size_t prev_size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
        GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
        Generation* prev_gen = gch->_gens[prev_level];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
        prev_size = prev_gen->capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
          gclog_or_tty->print_cr("  Younger gen size "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
                                 prev_size/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
      gclog_or_tty->print_cr("  unsafe_max_alloc_nogc "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
        unsafe_max_alloc_nogc()/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
      gclog_or_tty->print_cr("  contiguous available "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
        contiguous_available()/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
      gclog_or_tty->print_cr("  Expand by "SIZE_FORMAT" (bytes)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
        expand_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
    // safe if expansion fails
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
    expand(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
      gclog_or_tty->print_cr("  Expanded free fraction %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
        ((double) free()) / capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
Mutex* ConcurrentMarkSweepGeneration::freelistLock() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
  return cmsSpace()->freelistLock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
HeapWord* ConcurrentMarkSweepGeneration::allocate(size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
                                                  bool   tlab) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
  CMSSynchronousYieldRequest yr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
  MutexLockerEx x(freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
                  Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
  return have_lock_and_allocate(size, tlab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
HeapWord* ConcurrentMarkSweepGeneration::have_lock_and_allocate(size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
                                                  bool   tlab) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
  size_t adjustedSize = CompactibleFreeListSpace::adjustObjectSize(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
  HeapWord* res = cmsSpace()->allocate(adjustedSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
  // Allocate the object live (grey) if the background collector has
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
  // started marking. This is necessary because the marker may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
  // have passed this address and consequently this object will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
  // not otherwise be greyed and would be incorrectly swept up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
  // Note that if this object contains references, the writing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
  // of those references will dirty the card containing this object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
  // allowing the object to be blackened (and its references scanned)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
  // either during a preclean phase or at the final checkpoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
  if (res != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
    collector()->direct_allocated(res, adjustedSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
    _direct_allocated_words += adjustedSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
    // allocation counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
      _numObjectsAllocated++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
      _numWordsAllocated += (int)adjustedSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
// In the case of direct allocation by mutators in a generation that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
// is being concurrently collected, the object must be allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
// live (grey) if the background collector has started marking.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
// This is necessary because the marker may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
// have passed this address and consequently this object will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
// not otherwise be greyed and would be incorrectly swept up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
// Note that if this object contains references, the writing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
// of those references will dirty the card containing this object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
// allowing the object to be blackened (and its references scanned)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
// either during a preclean phase or at the final checkpoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
void CMSCollector::direct_allocated(HeapWord* start, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
  assert(_markBitMap.covers(start, size), "Out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
  if (_collectorState >= Marking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
    MutexLockerEx y(_markBitMap.lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
                    Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
    // [see comments preceding SweepClosure::do_blk() below for details]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
    // 1. need to mark the object as live so it isn't collected
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
    // 2. need to mark the 2nd bit to indicate the object may be uninitialized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
    // 3. need to mark the end of the object so sweeper can skip over it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
    //    if it's uninitialized when the sweeper reaches it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
    _markBitMap.mark(start);          // object is live
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
    _markBitMap.mark(start + 1);      // object is potentially uninitialized?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
    _markBitMap.mark(start + size - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
                                      // mark end of object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
  // check that oop looks uninitialized
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1044
  assert(oop(start)->klass_or_null() == NULL, "_klass should be NULL");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
void CMSCollector::promoted(bool par, HeapWord* start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
                            bool is_obj_array, size_t obj_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
  assert(_markBitMap.covers(start), "Out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
  // See comment in direct_allocated() about when objects should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
  // be allocated live.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
  if (_collectorState >= Marking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
    // we already hold the marking bit map lock, taken in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
    // the prologue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
    if (par) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
      _markBitMap.par_mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
      _markBitMap.mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
    // We don't need to mark the object as uninitialized (as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
    // in direct_allocated above) because this is being done with the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
    // world stopped and the object will be initialized by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
    // time the sweeper gets to look at it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
    assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
           "expect promotion only at safepoints");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
    if (_collectorState < Sweeping) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
      // Mark the appropriate cards in the modUnionTable, so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
      // this object gets scanned before the sweep. If this is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
      // not done, CMS generation references in the object might
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
      // not get marked.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
      // For the case of arrays, which are otherwise precisely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
      // marked, we need to dirty the entire array, not just its head.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
      if (is_obj_array) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
        // The [par_]mark_range() method expects mr.end() below to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
        // be aligned to the granularity of a bit's representation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
        // in the heap. In the case of the MUT below, that's a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
        // card size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
        MemRegion mr(start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
                     (HeapWord*)round_to((intptr_t)(start + obj_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
                        CardTableModRefBS::card_size /* bytes */));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
        if (par) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
          _modUnionTable.par_mark_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
          _modUnionTable.mark_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
      } else {  // not an obj array; we can just mark the head
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
        if (par) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
          _modUnionTable.par_mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
          _modUnionTable.mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
static inline size_t percent_of_space(Space* space, HeapWord* addr)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
  size_t delta = pointer_delta(addr, space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
  return (size_t)(delta * 100.0 / (space->capacity() / HeapWordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
void CMSCollector::icms_update_allocation_limits()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
  Generation* gen0 = GenCollectedHeap::heap()->get_gen(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
  EdenSpace* eden = gen0->as_DefNewGeneration()->eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
  const unsigned int duty_cycle = stats().icms_update_duty_cycle();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
  if (CMSTraceIncrementalPacing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
    stats().print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
  assert(duty_cycle <= 100, "invalid duty cycle");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
  if (duty_cycle != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
    // The duty_cycle is a percentage between 0 and 100; convert to words and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
    // then compute the offset from the endpoints of the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
    size_t free_words = eden->free() / HeapWordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
    double free_words_dbl = (double)free_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
    size_t duty_cycle_words = (size_t)(free_words_dbl * duty_cycle / 100.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
    size_t offset_words = (free_words - duty_cycle_words) / 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
    _icms_start_limit = eden->top() + offset_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
    _icms_stop_limit = eden->end() - offset_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
    // The limits may be adjusted (shifted to the right) by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
    // CMSIncrementalOffset, to allow the application more mutator time after a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
    // young gen gc (when all mutators were stopped) and before CMS starts and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
    // takes away one or more cpus.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
    if (CMSIncrementalOffset != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
      double adjustment_dbl = free_words_dbl * CMSIncrementalOffset / 100.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
      size_t adjustment = (size_t)adjustment_dbl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
      HeapWord* tmp_stop = _icms_stop_limit + adjustment;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
      if (tmp_stop > _icms_stop_limit && tmp_stop < eden->end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
        _icms_start_limit += adjustment;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
        _icms_stop_limit = tmp_stop;
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
  if (duty_cycle == 0 || (_icms_start_limit == _icms_stop_limit)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
    _icms_start_limit = _icms_stop_limit = eden->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
  // Install the new start limit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
  eden->set_soft_end(_icms_start_limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
  if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
    gclog_or_tty->print(" icms alloc limits:  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
                           PTR_FORMAT "," PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
                           " (" SIZE_FORMAT "%%," SIZE_FORMAT "%%) ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
                           _icms_start_limit, _icms_stop_limit,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
                           percent_of_space(eden, _icms_start_limit),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
                           percent_of_space(eden, _icms_stop_limit));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
    if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
      gclog_or_tty->print("eden:  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
      eden->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
// Any changes here should try to maintain the invariant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
// that if this method is called with _icms_start_limit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
// and _icms_stop_limit both NULL, then it should return NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
// and not notify the icms thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
CMSCollector::allocation_limit_reached(Space* space, HeapWord* top,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
                                       size_t word_size)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
  // A start_limit equal to end() means the duty cycle is 0, so treat that as a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
  // nop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
  if (CMSIncrementalMode && _icms_start_limit != space->end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
    if (top <= _icms_start_limit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
      if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
        space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
        gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
        gclog_or_tty->print_cr(" start limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
                               ", new limit=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
                               " (" SIZE_FORMAT "%%)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
                               top, _icms_stop_limit,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
                               percent_of_space(space, _icms_stop_limit));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
      ConcurrentMarkSweepThread::start_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
      assert(top < _icms_stop_limit, "Tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
      if (word_size < pointer_delta(_icms_stop_limit, top)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
        return _icms_stop_limit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
      // The allocation will cross both the _start and _stop limits, so do the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
      // stop notification also and return end().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
      if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
        space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
        gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
        gclog_or_tty->print_cr(" +stop limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
                               ", new limit=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
                               " (" SIZE_FORMAT "%%)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
                               top, space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
                               percent_of_space(space, space->end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
      ConcurrentMarkSweepThread::stop_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
      return space->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
    if (top <= _icms_stop_limit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
      if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
        space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
        gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
        gclog_or_tty->print_cr(" stop limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
                               ", new limit=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
                               " (" SIZE_FORMAT "%%)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
                               top, space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
                               percent_of_space(space, space->end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
      ConcurrentMarkSweepThread::stop_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
      return space->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
    if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
      space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
      gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
      gclog_or_tty->print_cr(" end limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
                             ", new limit=" PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
                             top, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  1229
oop ConcurrentMarkSweepGeneration::promote(oop obj, size_t obj_size) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
  assert(obj_size == (size_t)obj->size(), "bad obj_size passed in");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
  // allocate, copy and if necessary update promoinfo --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
  // delegate to underlying space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
  if (Universe::heap()->promotion_should_fail()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
#endif  // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  1241
  oop res = _cmsSpace->promote(obj, obj_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
  if (res == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
    // expand and retry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
    size_t s = _cmsSpace->expansionSpaceRequired(obj_size);  // HeapWords
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
    expand(s*HeapWordSize, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
      CMSExpansionCause::_satisfy_promotion);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
    // Since there's currently no next generation, we don't try to promote
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
    // into a more senior generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
    assert(next_gen() == NULL, "assumption, based upon which no attempt "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
                               "is made to pass on a possibly failing "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
                               "promotion to next generation");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  1252
    res = _cmsSpace->promote(obj, obj_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
  if (res != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
    // See comment in allocate() about when objects should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
    // be allocated live.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
    assert(obj->is_oop(), "Will dereference klass pointer below");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
    collector()->promoted(false,           // Not parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
                          (HeapWord*)res, obj->is_objArray(), obj_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
    // promotion counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
      _numObjectsPromoted++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
      _numWordsPromoted +=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
        (int)(CompactibleFreeListSpace::adjustObjectSize(obj->size()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
  return res;
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
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
ConcurrentMarkSweepGeneration::allocation_limit_reached(Space* space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
                                             HeapWord* top,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
                                             size_t word_sz)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
  return collector()->allocation_limit_reached(space, top, word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
// Things to support parallel young-gen collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
ConcurrentMarkSweepGeneration::par_promote(int thread_num,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
                                           oop old, markOop m,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
                                           size_t word_sz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
  if (Universe::heap()->promotion_should_fail()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
#endif  // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
  CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
  PromotionInfo* promoInfo = &ps->promo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
  // if we are tracking promotions, then first ensure space for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
  // promotion (including spooling space for saving header if necessary).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
  // then allocate and copy, then track promoted info if needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
  // When tracking (see PromotionInfo::track()), the mark word may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
  // be displaced and in this case restoration of the mark word
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
  // occurs in the (oop_since_save_marks_)iterate phase.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
  if (promoInfo->tracking() && !promoInfo->ensure_spooling_space()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
    // Out of space for allocating spooling buffers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
    // try expanding and allocating spooling buffers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
    if (!expand_and_ensure_spooling_space(promoInfo)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
  assert(promoInfo->has_spooling_space(), "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
  HeapWord* obj_ptr = ps->lab.alloc(word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
  if (obj_ptr == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
     obj_ptr = expand_and_par_lab_allocate(ps, word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
     if (obj_ptr == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
       return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
  oop obj = oop(obj_ptr);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1314
  assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
  // Otherwise, copy the object.  Here we must be careful to insert the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
  // 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
  1317
  // Except with compressed oops it's the mark word.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
  HeapWord* old_ptr = (HeapWord*)old;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
  if (word_sz > (size_t)oopDesc::header_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
    Copy::aligned_disjoint_words(old_ptr + oopDesc::header_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
                                 obj_ptr + oopDesc::header_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
                                 word_sz - oopDesc::header_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
  }
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1324
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1325
  if (UseCompressedOops) {
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1326
    // Copy gap missed by (aligned) header size calculation above
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1327
    obj->set_klass_gap(old->klass_gap());
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1328
  }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1329
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
  // Restore the mark word copied above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
  obj->set_mark(m);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1332
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
  // Now we can track the promoted object, if necessary.  We take care
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
  // To delay the transition from uninitialized to full object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
  // (i.e., insertion of klass pointer) until after, so that it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
  // atomically becomes a promoted object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
  if (promoInfo->tracking()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
    promoInfo->track((PromotedObject*)obj, old->klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
  }
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1340
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1341
  // Finally, install the klass pointer (this should be volatile).
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
  obj->set_klass(old->klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
  assert(old->is_oop(), "Will dereference klass ptr below");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
  collector()->promoted(true,          // parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
                        obj_ptr, old->is_objArray(), word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1349
    Atomic::inc(&_numObjectsPromoted);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1350
    Atomic::add((jint)CompactibleFreeListSpace::adjustObjectSize(obj->size()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1351
                &_numWordsPromoted);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1352
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1353
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
  return obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1355
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
ConcurrentMarkSweepGeneration::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
par_promote_alloc_undo(int thread_num,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1360
                       HeapWord* obj, size_t word_sz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1361
  // CMS does not support promotion undo.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1362
  ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
ConcurrentMarkSweepGeneration::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
par_promote_alloc_done(int thread_num) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
  CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
  ps->lab.retire();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
#if CFLS_LAB_REFILL_STATS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
  if (thread_num == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
    _cmsSpace->print_par_alloc_stats();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
ConcurrentMarkSweepGeneration::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
par_oop_since_save_marks_iterate_done(int thread_num) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
  CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
  ParScanWithoutBarrierClosure* dummy_cl = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
  ps->promo.promoted_oops_iterate_nv(dummy_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
// XXXPERM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
bool ConcurrentMarkSweepGeneration::should_collect(bool   full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
                                                   size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
                                                   bool   tlab)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
  // We allow a STW collection only if a full
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
  // collection was requested.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
  return full || should_allocate(size, tlab); // FIX ME !!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
  // This and promotion failure handling are connected at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
  // hip and should be fixed by untying them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
bool CMSCollector::shouldConcurrentCollect() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
  if (_full_gc_requested) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
    assert(ExplicitGCInvokesConcurrent, "Unexpected state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
      gclog_or_tty->print_cr("CMSCollector: collect because of explicit "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
                             " gc request");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1403
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
  // For debugging purposes, change the type of collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
  // If the rotation is not on the concurrent collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
  // type, don't start a concurrent collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
    if (RotateCMSCollectionTypes &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
        (_cmsGen->debug_collection_type() !=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
          ConcurrentMarkSweepGeneration::Concurrent_collection_type)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
      assert(_cmsGen->debug_collection_type() !=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
        ConcurrentMarkSweepGeneration::Unknown_collection_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
        "Bad cms collection type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
  FreelistLocker x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
  // ------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
  // Print out lots of information which affects the initiation of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
  // a collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
  if (PrintCMSInitiationStatistics && stats().valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
    gclog_or_tty->print("CMSCollector shouldConcurrentCollect: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
    gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
    gclog_or_tty->print_cr("");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
    stats().print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
    gclog_or_tty->print_cr("time_until_cms_gen_full %3.7f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
      stats().time_until_cms_gen_full());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
    gclog_or_tty->print_cr("free="SIZE_FORMAT, _cmsGen->free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
    gclog_or_tty->print_cr("contiguous_available="SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
                           _cmsGen->contiguous_available());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
    gclog_or_tty->print_cr("promotion_rate=%g", stats().promotion_rate());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
    gclog_or_tty->print_cr("cms_allocation_rate=%g", stats().cms_allocation_rate());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
    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
  1438
    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
  1439
    gclog_or_tty->print_cr("initiatingPermOccupancy=%3.7f", _permGen->initiating_occupancy());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
  // ------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
  // If the estimated time to complete a cms collection (cms_duration())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
  // is less than the estimated time remaining until the cms generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
  // is full, start a collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
  if (!UseCMSInitiatingOccupancyOnly) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
    if (stats().valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
      if (stats().time_until_cms_start() == 0.0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
        return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
      // We want to conservatively collect somewhat early in order
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
      // to try and "bootstrap" our CMS/promotion statistics;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
      // this branch will not fire after the first successful CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
      // collection because the stats should then be valid.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
      if (_cmsGen->occupancy() >= _bootstrap_occupancy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
        if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
          gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
            " CMSCollector: collect for bootstrapping statistics:"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
            " occupancy = %f, boot occupancy = %f", _cmsGen->occupancy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
            _bootstrap_occupancy);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
        return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
  // Otherwise, we start a collection cycle if either the perm gen or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
  // old gen want a collection cycle started. Each may use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
  // an appropriate criterion for making this decision.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
  // 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
  1472
  // 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
  1473
  if (_cmsGen->should_concurrent_collect()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
      gclog_or_tty->print_cr("CMS old gen initiated");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1480
  // 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
  1481
  // 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
  1482
  // late anyway.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1483
  GenCollectedHeap* gch = GenCollectedHeap::heap();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1484
  assert(gch->collector_policy()->is_two_generation_policy(),
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1485
         "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
  1486
  if (gch->incremental_collection_will_fail()) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1487
    if (PrintGCDetails && Verbose) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1488
      gclog_or_tty->print("CMSCollector: collect because incremental collection will fail ");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1493
  if (CMSClassUnloadingEnabled && _permGen->should_concurrent_collect()) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1494
    bool res = update_should_unload_classes();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1495
    if (res) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1496
      if (Verbose && PrintGCDetails) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1497
        gclog_or_tty->print_cr("CMS perm gen initiated");
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1498
      }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1499
      return true;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1500
    }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1501
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
// Clear _expansion_cause fields of constituent generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
void CMSCollector::clear_expansion_cause() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
  _cmsGen->clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
  _permGen->clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1511
// 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
  1512
// 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
  1513
// 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
  1514
// 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
  1515
// 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
  1516
// UseCMSInitiatingOccupancyOnly.  This also has the advantage of
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1517
// 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
  1518
// collections.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1519
// 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
  1520
// conditions hold:
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1521
// . our current occupancy exceeds the configured initiating occupancy
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1522
//   for this generation, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1523
// . 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
  1524
//   expansion, done a collection of this generation, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1525
// . 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
  1526
//   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
  1527
//   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
  1528
//   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
  1529
//   the generation, etc... or ...
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1530
// [.(currently done by CMSCollector::shouldConcurrentCollect() only for
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1531
//   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
  1532
//   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
  1533
//   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
  1534
bool ConcurrentMarkSweepGeneration::should_concurrent_collect() const {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1535
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
  assert_lock_strong(freelistLock());
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1537
  if (occupancy() > initiating_occupancy()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
      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
  1540
        short_name(), occupancy(), initiating_occupancy());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
  if (UseCMSInitiatingOccupancyOnly) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
  if (expansion_cause() == CMSExpansionCause::_satisfy_allocation) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
      gclog_or_tty->print(" %s: collect because expanded for allocation ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
        short_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
  }
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1554
  if (_cmsSpace->should_concurrent_collect()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
    if (PrintGCDetails && Verbose) {
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1556
      gclog_or_tty->print(" %s: collect because cmsSpace says so ",
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
        short_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
void ConcurrentMarkSweepGeneration::collect(bool   full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
                                            bool   clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
                                            size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
                                            bool   tlab)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
  collector()->collect(full, clear_all_soft_refs, size, tlab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
void CMSCollector::collect(bool   full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
                           bool   clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
                           size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1575
                           bool   tlab)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1576
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
  if (!UseCMSCollectionPassing && _collectorState > Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1578
    // For debugging purposes skip the collection if the state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1579
    // is not currently idle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1580
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1581
      gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " skipped full:%d CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1582
        Thread::current(), full, _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1584
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1585
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1586
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1587
  // The following "if" branch is present for defensive reasons.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1588
  // In the current uses of this interface, it can be replaced with:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1589
  // assert(!GC_locker.is_active(), "Can't be called otherwise");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1590
  // But I am not placing that assert here to allow future
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1591
  // generality in invoking this interface.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1592
  if (GC_locker::is_active()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1593
    // A consistency test for GC_locker
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
    assert(GC_locker::needs_gc(), "Should have been set already");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
    // Skip this foreground collection, instead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
    // expanding the heap if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
    // Need the free list locks for the call to free() in compute_new_size()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
    compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
  acquire_control_and_collect(full, clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
  _full_gcs_since_conc_gc++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1606
void CMSCollector::request_full_gc(unsigned int full_gc_count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
  unsigned int gc_count = gch->total_full_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
  if (gc_count == full_gc_count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
    MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
    _full_gc_requested = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
    CGC_lock->notify();   // nudge CMS thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
// The foreground and background collectors need to coordinate in order
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1618
// to make sure that they do not mutually interfere with CMS collections.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
// When a background collection is active,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1620
// the foreground collector may need to take over (preempt) and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1621
// synchronously complete an ongoing collection. Depending on the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1622
// frequency of the background collections and the heap usage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
// of the application, this preemption can be seldom or frequent.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1624
// There are only certain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1625
// points in the background collection that the "collection-baton"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1626
// can be passed to the foreground collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
// The foreground collector will wait for the baton before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
// starting any part of the collection.  The foreground collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
// will only wait at one location.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
// The background collector will yield the baton before starting a new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
// phase of the collection (e.g., before initial marking, marking from roots,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
// precleaning, final re-mark, sweep etc.)  This is normally done at the head
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
// of the loop which switches the phases. The background collector does some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
// of the phases (initial mark, final re-mark) with the world stopped.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1637
// Because of locking involved in stopping the world,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1638
// the foreground collector should not block waiting for the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
// collector when it is doing a stop-the-world phase.  The background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
// collector will yield the baton at an additional point just before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
// it enters a stop-the-world phase.  Once the world is stopped, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
// background collector checks the phase of the collection.  If the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
// phase has not changed, it proceeds with the collection.  If the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1644
// phase has changed, it skips that phase of the collection.  See
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1645
// the comments on the use of the Heap_lock in collect_in_background().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1647
// Variable used in baton passing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
//   _foregroundGCIsActive - Set to true by the foreground collector when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
//      it wants the baton.  The foreground clears it when it has finished
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1650
//      the collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1651
//   _foregroundGCShouldWait - Set to true by the background collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1652
//        when it is running.  The foreground collector waits while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1653
//      _foregroundGCShouldWait is true.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1654
//  CGC_lock - monitor used to protect access to the above variables
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1655
//      and to notify the foreground and background collectors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1656
//  _collectorState - current state of the CMS collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1658
// The foreground collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
//   acquires the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
//   sets _foregroundGCIsActive
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1661
//   waits on the CGC_lock for _foregroundGCShouldWait to be false
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
//     various locks acquired in preparation for the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
//     are released so as not to block the background collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
//     that is in the midst of a collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
//   proceeds with the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
//   clears _foregroundGCIsActive
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
//   returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1669
// The background collector in a loop iterating on the phases of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
//      collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
//   acquires the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
//   sets _foregroundGCShouldWait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
//   if _foregroundGCIsActive is set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
//     clears _foregroundGCShouldWait, notifies _CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
//     waits on _CGC_lock for _foregroundGCIsActive to become false
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
//     and exits the loop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
//   otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
//     proceed with that phase of the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
//     if the phase is a stop-the-world phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
//       yield the baton once more just before enqueueing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
//       the stop-world CMS operation (executed by the VM thread).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
//   returns after all phases of the collection are done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
void CMSCollector::acquire_control_and_collect(bool full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
        bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
  assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
  assert(!Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
         "shouldn't try to acquire control from self!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
  // Start the protocol for acquiring control of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
  // collection from the background collector (aka CMS thread).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
  assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
         "VM thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
  // Remember the possibly interrupted state of an ongoing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
  // concurrent collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
  CollectorState first_state = _collectorState;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
  // Signal to a possibly ongoing concurrent collection that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
  // we want to do a foreground collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
  _foregroundGCIsActive = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
  // Disable incremental mode during a foreground collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
  ICMSDisabler icms_disabler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
  // release locks and wait for a notify from the background collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
  // releasing the locks in only necessary for phases which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
  // do yields to improve the granularity of the collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
  // We need to lock the Free list lock for the space that we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
  // currently collecting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
  assert(haveFreelistLocks(), "Must be holding free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
  bitMapLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1714
  releaseFreelistLocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1717
    if (_foregroundGCShouldWait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
      // We are going to be waiting for action for the CMS thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
      // it had better not be gone (for instance at shutdown)!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
      assert(ConcurrentMarkSweepThread::cmst() != NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
             "CMS thread must be running");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
      // Wait here until the background collector gives us the go-ahead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
      ConcurrentMarkSweepThread::clear_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
        ConcurrentMarkSweepThread::CMS_vm_has_token);  // release token
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
      // Get a possibly blocked CMS thread going:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
      //   Note that we set _foregroundGCIsActive true above,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
      //   without protection of the CGC_lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
      CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
      assert(!ConcurrentMarkSweepThread::vm_thread_wants_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
             "Possible deadlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
      while (_foregroundGCShouldWait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
        // wait for notification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
        CGC_lock->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
        // Possibility of delay/starvation here, since CMS token does
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
        // not know to give priority to VM thread? Actually, i think
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
        // there wouldn't be any delay/starvation, but the proof of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
        // that "fact" (?) appears non-trivial. XXX 20011219YSR
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
      ConcurrentMarkSweepThread::set_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
        ConcurrentMarkSweepThread::CMS_vm_has_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
  // The CMS_token is already held.  Get back the other locks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
  assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
         "VM thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
  getFreelistLocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
  bitMapLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
    gclog_or_tty->print_cr("CMS foreground collector has asked for control "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
      INTPTR_FORMAT " with first state %d", Thread::current(), first_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
    gclog_or_tty->print_cr("    gets control with state %d", _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
  // Check if we need to do a compaction, or if not, whether
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
  // we need to start the mark-sweep from scratch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
  bool should_compact    = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
  bool should_start_over = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
  decide_foreground_collection_type(clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
    &should_compact, &should_start_over);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
  if (RotateCMSCollectionTypes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
    if (_cmsGen->debug_collection_type() ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
        ConcurrentMarkSweepGeneration::MSC_foreground_collection_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
      should_compact = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
    } else if (_cmsGen->debug_collection_type() ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
               ConcurrentMarkSweepGeneration::MS_foreground_collection_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
      should_compact = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
  if (PrintGCDetails && first_state > Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1774
    GCCause::Cause cause = GenCollectedHeap::heap()->gc_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1775
    if (GCCause::is_user_requested_gc(cause) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1776
        GCCause::is_serviceability_requested_gc(cause)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
      gclog_or_tty->print(" (concurrent mode interrupted)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1779
      gclog_or_tty->print(" (concurrent mode failure)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1780
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1783
  if (should_compact) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1784
    // If the collection is being acquired from the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1785
    // collector, there may be references on the discovered
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
    // references lists that have NULL referents (being those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1787
    // that were concurrently cleared by a mutator) or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1788
    // that are no longer active (having been enqueued concurrently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1789
    // by the mutator).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1790
    // Scrub the list of those references because Mark-Sweep-Compact
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
    // code assumes referents are not NULL and that all discovered
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
    // Reference objects are active.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
    ref_processor()->clean_up_discovered_references();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
    do_compaction_work(clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
    // Has the GC time limit been exceeded?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
    check_gc_time_limit();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1799
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
    do_mark_sweep_work(clear_all_soft_refs, first_state,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
      should_start_over);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1804
  // Reset the expansion cause, now that we just completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1805
  // a collection cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1806
  clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
  _foregroundGCIsActive = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
void CMSCollector::check_gc_time_limit() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
  // Ignore explicit GC's.  Exiting here does not set the flag and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
  // does not reset the count.  Updating of the averages for system
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
  // GC's is still controlled by UseAdaptiveSizePolicyWithSystemGC.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
  GCCause::Cause gc_cause = GenCollectedHeap::heap()->gc_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
  if (GCCause::is_user_requested_gc(gc_cause) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
      GCCause::is_serviceability_requested_gc(gc_cause)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1819
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1820
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1821
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
  // Calculate the fraction of the CMS generation was freed during
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
  // the last collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
  // Only consider the STW compacting cost for now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1825
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
  // Note that the gc time limit test only works for the collections
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
  // of the young gen + tenured gen and not for collections of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1828
  // permanent gen.  That is because the calculation of the space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
  // freed by the collection is the free space in the young gen +
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
  // tenured gen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1831
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1832
  double fraction_free =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1833
    ((double)_cmsGen->free())/((double)_cmsGen->max_capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1834
  if ((100.0 * size_policy()->compacting_gc_cost()) >
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1835
         ((double) GCTimeLimit) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1836
        ((fraction_free * 100) < GCHeapFreeLimit)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1837
    size_policy()->inc_gc_time_limit_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
    if (UseGCOverheadLimit &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
        (size_policy()->gc_time_limit_count() >
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
         AdaptiveSizePolicyGCTimeLimitThreshold)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
      size_policy()->set_gc_time_limit_exceeded(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
      // Avoid consecutive OOM due to the gc time limit by resetting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
      // the counter.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
      size_policy()->reset_gc_time_limit_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
      if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
        gclog_or_tty->print_cr("      GC is exceeding overhead limit "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
          "of %d%%", GCTimeLimit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1848
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1850
      if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1851
        gclog_or_tty->print_cr("      GC would exceed overhead limit "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
          "of %d%%", GCTimeLimit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1854
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1855
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1856
    size_policy()->reset_gc_time_limit_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1857
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1858
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1859
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1860
// Resize the perm generation and the tenured generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1861
// after obtaining the free list locks for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1862
// two generations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1863
void CMSCollector::compute_new_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1864
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1865
  FreelistLocker z(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1866
  _permGen->compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1867
  _cmsGen->compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
// A work method used by foreground collection to determine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
// what type of collection (compacting or not, continuing or fresh)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1872
// it should do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
// NOTE: the intent is to make UseCMSCompactAtFullCollection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
// and CMSCompactWhenClearAllSoftRefs the default in the future
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1875
// and do away with the flags after a suitable period.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1876
void CMSCollector::decide_foreground_collection_type(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1877
  bool clear_all_soft_refs, bool* should_compact,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1878
  bool* should_start_over) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1879
  // Normally, we'll compact only if the UseCMSCompactAtFullCollection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1880
  // flag is set, and we have either requested a System.gc() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1881
  // the number of full gc's since the last concurrent cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1882
  // has exceeded the threshold set by CMSFullGCsBeforeCompaction,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1883
  // or if an incremental collection has failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1884
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1885
  assert(gch->collector_policy()->is_two_generation_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1886
         "You may want to check the correctness of the following");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1887
  // Inform cms gen if this was due to partial collection failing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1888
  // The CMS gen may use this fact to determine its expansion policy.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1889
  if (gch->incremental_collection_will_fail()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1890
    assert(!_cmsGen->incremental_collection_failed(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1891
           "Should have been noticed, reacted to and cleared");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1892
    _cmsGen->set_incremental_collection_failed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1893
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1894
  *should_compact =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1895
    UseCMSCompactAtFullCollection &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1896
    ((_full_gcs_since_conc_gc >= CMSFullGCsBeforeCompaction) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1897
     GCCause::is_user_requested_gc(gch->gc_cause()) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1898
     gch->incremental_collection_will_fail());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1899
  *should_start_over = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1900
  if (clear_all_soft_refs && !*should_compact) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1901
    // We are about to do a last ditch collection attempt
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
    // so it would normally make sense to do a compaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
    // to reclaim as much space as possible.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
    if (CMSCompactWhenClearAllSoftRefs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
      // Default: The rationale is that in this case either
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
      // we are past the final marking phase, in which case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
      // we'd have to start over, or so little has been done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
      // that there's little point in saving that work. Compaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
      // appears to be the sensible choice in either case.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
      *should_compact = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
      // We have been asked to clear all soft refs, but not to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
      // compact. Make sure that we aren't past the final checkpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
      // phase, for that is where we process soft refs. If we are already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
      // past that phase, we'll need to redo the refs discovery phase and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
      // if necessary clear soft refs that weren't previously
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
      // cleared. We do so by remembering the phase in which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
      // we came in, and if we are past the refs processing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
      // phase, we'll choose to just redo the mark-sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
      // collection from scratch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
      if (_collectorState > FinalMarking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
        // We are past the refs processing phase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
        // start over and do a fresh synchronous CMS cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
        _collectorState = Resetting; // skip to reset to start new cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
        reset(false /* == !asynch */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
        *should_start_over = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
      } // else we can continue a possibly ongoing current cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
// A work method used by the foreground collector to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
// a mark-sweep-compact.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
  TraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
  if (PrintGC && Verbose && !(GCCause::is_user_requested_gc(gch->gc_cause()))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
    gclog_or_tty->print_cr("Compact ConcurrentMarkSweepGeneration after %d "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
      "collections passed to foreground collector", _full_gcs_since_conc_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
  // Sample collection interval time and reset for collection pause.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
    size_policy()->msc_collection_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
  // Temporarily widen the span of the weak reference processing to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
  // the entire heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
  MemRegion new_span(GenCollectedHeap::heap()->reserved_region());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
  ReferenceProcessorSpanMutator x(ref_processor(), new_span);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
  // Temporarily, clear the "is_alive_non_header" field of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
  // reference processor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
  ReferenceProcessorIsAliveMutator y(ref_processor(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
  // Temporarily make reference _processing_ single threaded (non-MT).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1957
  ReferenceProcessorMTProcMutator z(ref_processor(), false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1958
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1959
  // Temporarily make refs discovery atomic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
  ReferenceProcessorAtomicMutator w(ref_processor(), true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1961
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1962
  ref_processor()->set_enqueuing_is_done(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1963
  ref_processor()->enable_discovery();
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  1964
  ref_processor()->snap_policy(clear_all_soft_refs);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1965
  // If an asynchronous collection finishes, the _modUnionTable is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1966
  // all clear.  If we are assuming the collection from an asynchronous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
  // collection, clear the _modUnionTable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1968
  assert(_collectorState != Idling || _modUnionTable.isAllClear(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1969
    "_modUnionTable should be clear if the baton was not passed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
  _modUnionTable.clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
  // We must adjust the allocation statistics being maintained
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1973
  // in the free list space. We do so by reading and clearing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
  // the sweep timer and updating the block flux rate estimates below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
  assert(_sweep_timer.is_active(), "We should never see the timer inactive");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
  _sweep_timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
  // Note that we do not use this sample to update the _sweep_estimate.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1978
  _cmsGen->cmsSpace()->beginSweepFLCensus((float)(_sweep_timer.seconds()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1979
                                          _sweep_estimate.padded_average());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1981
  GenMarkSweep::invoke_at_safepoint(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1982
    ref_processor(), clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1983
  #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1984
    CompactibleFreeListSpace* cms_space = _cmsGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1985
    size_t free_size = cms_space->free();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1986
    assert(free_size ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1987
           pointer_delta(cms_space->end(), cms_space->compaction_top())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1988
           * HeapWordSize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1989
      "All the free space should be compacted into one chunk at top");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1990
    assert(cms_space->dictionary()->totalChunkSize(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1991
                                      debug_only(cms_space->freelistLock())) == 0 ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1992
           cms_space->totalSizeInIndexedFreeLists() == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1993
      "All the free space should be in a single chunk");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1994
    size_t num = cms_space->totalCount();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1995
    assert((free_size == 0 && num == 0) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1996
           (free_size > 0  && (num == 1 || num == 2)),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1997
         "There should be at most 2 free chunks after compaction");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1998
  #endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1999
  _collectorState = Resetting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2000
  assert(_restart_addr == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2001
         "Should have been NULL'd before baton was passed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2002
  reset(false /* == !asynch */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2003
  _cmsGen->reset_after_compaction();
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2004
  _concurrent_cycles_since_last_unload = 0;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2005
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2006
  if (verifying() && !should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
    perm_gen_verify_bit_map()->clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2008
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
  // Clear any data recorded in the PLAB chunk arrays.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
  if (_survivor_plab_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
    reset_survivor_plab_arrays();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
  // Adjust the per-size allocation stats for the next epoch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
  _cmsGen->cmsSpace()->endSweepFLCensus(sweepCount() /* fake */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
  // Restart the "sweep timer" for next epoch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
  _sweep_timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
  _sweep_timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2021
  // Sample collection pause time and reset for collection interval.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
    size_policy()->msc_collection_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2024
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
  // For a mark-sweep-compact, compute_new_size() will be called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
  // in the heap's do_collection() method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2029
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
// A work method used by the foreground collector to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
// a mark-sweep, after taking over from a possibly on-going
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
// concurrent mark-sweep collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
void CMSCollector::do_mark_sweep_work(bool clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2034
  CollectorState first_state, bool should_start_over) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
    gclog_or_tty->print_cr("Pass concurrent collection to foreground "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
      "collector with count %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2038
      _full_gcs_since_conc_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2040
  switch (_collectorState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
    case Idling:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2042
      if (first_state == Idling || should_start_over) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2043
        // The background GC was not active, or should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
        // restarted from scratch;  start the cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
        _collectorState = InitialMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2047
      // If first_state was not Idling, then a background GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
      // was in progress and has now finished.  No need to do it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
      // again.  Leave the state as Idling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
    case Precleaning:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2052
      // In the foreground case don't do the precleaning since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2053
      // it is not done concurrently and there is extra work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2054
      // required.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2055
      _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2056
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2057
  if (PrintGCDetails &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2058
      (_collectorState > Idling ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2059
       !GCCause::is_user_requested_gc(GenCollectedHeap::heap()->gc_cause()))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2060
    gclog_or_tty->print(" (concurrent mode failure)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2061
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2062
  collect_in_foreground(clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2063
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2064
  // For a mark-sweep, compute_new_size() will be called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2065
  // in the heap's do_collection() method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2066
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2067
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2068
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2069
void CMSCollector::getFreelistLocks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2070
  // Get locks for all free lists in all generations that this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2071
  // collector is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2072
  _cmsGen->freelistLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2073
  _permGen->freelistLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2074
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2075
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2076
void CMSCollector::releaseFreelistLocks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2077
  // Release locks for all free lists in all generations that this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2078
  // collector is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2079
  _cmsGen->freelistLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2080
  _permGen->freelistLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2081
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2082
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2083
bool CMSCollector::haveFreelistLocks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2084
  // Check locks for all free lists in all generations that this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2085
  // collector is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2086
  assert_lock_strong(_cmsGen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2087
  assert_lock_strong(_permGen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2088
  PRODUCT_ONLY(ShouldNotReachHere());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2089
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2090
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2091
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2092
// A utility class that is used by the CMS collector to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2093
// temporarily "release" the foreground collector from its
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2094
// usual obligation to wait for the background collector to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2095
// complete an ongoing phase before proceeding.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2096
class ReleaseForegroundGC: public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2097
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2098
  CMSCollector* _c;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2099
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2100
  ReleaseForegroundGC(CMSCollector* c) : _c(c) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2101
    assert(_c->_foregroundGCShouldWait, "Else should not need to call");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2102
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2103
    // allow a potentially blocked foreground collector to proceed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2104
    _c->_foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
    if (_c->_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2106
      CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2107
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
    assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
           "Possible deadlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
  ~ReleaseForegroundGC() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
    assert(!_c->_foregroundGCShouldWait, "Usage protocol violation?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2114
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
    _c->_foregroundGCShouldWait = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2118
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
// There are separate collect_in_background and collect_in_foreground because of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
// the different locking requirements of the background collector and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
// foreground collector.  There was originally an attempt to share
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
// one "collect" method between the background collector and the foreground
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
// collector but the if-then-else required made it cleaner to have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
// separate methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
void CMSCollector::collect_in_background(bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
  assert(Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
    "A CMS asynchronous collection is only allowed on a CMS thread.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
    bool safepoint_check = Mutex::_no_safepoint_check_flag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
    MutexLockerEx hl(Heap_lock, safepoint_check);
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2133
    FreelistLocker fll(this);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2134
    MutexLockerEx x(CGC_lock, safepoint_check);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
    if (_foregroundGCIsActive || !UseAsyncConcMarkSweepGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2136
      // The foreground collector is active or we're
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2137
      // not using asynchronous collections.  Skip this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2138
      // background collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2139
      assert(!_foregroundGCShouldWait, "Should be clear");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2140
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2141
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2142
      assert(_collectorState == Idling, "Should be idling before start.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2143
      _collectorState = InitialMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2144
      // Reset the expansion cause, now that we are about to begin
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2145
      // a new cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2146
      clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2147
    }
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2148
    // 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
  2149
    // ensuing concurrent GC cycle.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2150
    update_should_unload_classes();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2151
    _full_gc_requested = false;           // acks all outstanding full gc requests
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2152
    // Signal that we are about to start a collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2153
    gch->increment_total_full_collections();  // ... starting a collection cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2154
    _collection_count_start = gch->total_full_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2155
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2156
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2157
  // Used for PrintGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2158
  size_t prev_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2159
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2160
    prev_used = _cmsGen->used(); // XXXPERM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2161
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2162
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2163
  // The change of the collection state is normally done at this level;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2164
  // the exceptions are phases that are executed while the world is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2165
  // stopped.  For those phases the change of state is done while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2166
  // world is stopped.  For baton passing purposes this allows the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2167
  // background collector to finish the phase and change state atomically.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2168
  // The foreground collector cannot wait on a phase that is done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2169
  // while the world is stopped because the foreground collector already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2170
  // has the world stopped and would deadlock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2171
  while (_collectorState != Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2172
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
      gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " in CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
    // The foreground collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
    //   holds the Heap_lock throughout its collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
    //   holds the CMS token (but not the lock)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2179
    //     except while it is waiting for the background collector to yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2180
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2181
    // The foreground collector should be blocked (not for long)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
    //   if the background collector is about to start a phase
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
    //   executed with world stopped.  If the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
    //   collector has already started such a phase, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2185
    //   foreground collector is blocked waiting for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2186
    //   Heap_lock.  The stop-world phases (InitialMarking and FinalMarking)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2187
    //   are executed in the VM thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2189
    // The locking order is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
    //   PendingListLock (PLL)  -- if applicable (FinalMarking)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
    //   Heap_lock  (both this & PLL locked in VM_CMS_Operation::prologue())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2192
    //   CMS token  (claimed in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
    //                stop_world_and_do() -->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
    //                  safepoint_synchronize() -->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2195
    //                    CMSThread::synchronize())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2196
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2197
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2198
      // Check if the FG collector wants us to yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2199
      CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2200
      if (waitForForegroundGC()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2201
        // We yielded to a foreground GC, nothing more to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2202
        // done this round.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2203
        assert(_foregroundGCShouldWait == false, "We set it to false in "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
               "waitForForegroundGC()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
        if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
          gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2207
            " exiting collection CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2208
            Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2209
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2211
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
        // The background collector can run but check to see if the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
        // foreground collector has done a collection while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
        // background collector was waiting to get the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
        // above.  If yes, break so that _foregroundGCShouldWait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
        // is cleared before returning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
        if (_collectorState == Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
    assert(_foregroundGCShouldWait, "Foreground collector, if active, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2224
      "should be waiting");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2225
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2226
    switch (_collectorState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2227
      case InitialMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2228
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2229
          ReleaseForegroundGC x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2230
          stats().record_cms_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2231
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2232
          VM_CMS_Initial_Mark initial_mark_op(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
          VMThread::execute(&initial_mark_op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
        // The collector state may be any legal state at this point
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
        // since the background collector may have yielded to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
        // foreground collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
      case Marking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
        // initial marking in checkpointRootsInitialWork has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
        if (markFromRoots(true)) { // we were successful
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
          assert(_collectorState == Precleaning, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
            "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
          assert(_foregroundGCIsActive, "Internal state inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
      case Precleaning:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
          size_policy()->concurrent_precleaning_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
        // marking from roots in markFromRoots has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
        preclean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2254
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
          size_policy()->concurrent_precleaning_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
        assert(_collectorState == AbortablePreclean ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
               _collectorState == FinalMarking,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2259
               "Collector state should have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2260
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2261
      case AbortablePreclean:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
        size_policy()->concurrent_phases_resume();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
        abortable_preclean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
          size_policy()->concurrent_precleaning_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
        assert(_collectorState == FinalMarking, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
          "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
      case FinalMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2273
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
          ReleaseForegroundGC x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
          VM_CMS_Final_Remark final_remark_op(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
          VMThread::execute(&final_remark_op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
        assert(_foregroundGCShouldWait, "block post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
      case Sweeping:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
          size_policy()->concurrent_sweeping_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
        // final marking in checkpointRootsFinal has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2286
        sweep(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
        assert(_collectorState == Resizing, "Collector state change "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2288
          "to Resizing must be done under the free_list_lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
        _full_gcs_since_conc_gc = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
        // Stop the timers for adaptive size policy for the concurrent phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
          size_policy()->concurrent_sweeping_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
          size_policy()->concurrent_phases_end(gch->gc_cause(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
                                             gch->prev_gen(_cmsGen)->capacity(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
                                             _cmsGen->free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
      case Resizing: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
        // Sweeping has been completed...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
        // At this point the background collection has completed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
        // Don't move the call to compute_new_size() down
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
        // into code that might be executed if the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
        // collection was preempted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
          ReleaseForegroundGC x(this);   // unblock FG collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
          MutexLockerEx       y(Heap_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
          CMSTokenSync        z(true);   // not strictly needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
          if (_collectorState == Resizing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
            compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
            _collectorState = Resetting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2313
            assert(_collectorState == Idling, "The state should only change"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2314
                   " because the foreground collector has finished the collection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2317
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2318
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
      case Resetting:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2320
        // CMS heap resizing has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
        reset(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
        assert(_collectorState == Idling, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
          "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2324
        stats().record_cms_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
        // Don't move the concurrent_phases_end() and compute_new_size()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
        // calls to here because a preempted background collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
        // has it's state set to "Resetting".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
      case Idling:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
        ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2335
      gclog_or_tty->print_cr("  Thread " INTPTR_FORMAT " done - next CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2336
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2337
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2338
    assert(_foregroundGCShouldWait, "block post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2339
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2340
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2341
  // Should this be in gc_epilogue?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
  collector_policy()->counters()->update_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2343
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
    // Clear _foregroundGCShouldWait and, in the event that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
    // foreground collector is waiting, notify it, before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
    // returning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
    _foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
    if (_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
      CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
    assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
           "Possible deadlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
      " exiting collection CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
      Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2360
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2361
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2362
    _cmsGen->print_heap_change(prev_used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2363
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2365
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2366
void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2367
  assert(_foregroundGCIsActive && !_foregroundGCShouldWait,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2368
         "Foreground collector should be waiting, not executing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2369
  assert(Thread::current()->is_VM_thread(), "A foreground collection"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2370
    "may only be done by the VM Thread with the world stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2371
  assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2372
         "VM thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2373
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2374
  NOT_PRODUCT(TraceTime t("CMS:MS (foreground) ", PrintGCDetails && Verbose,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2375
    true, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2376
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2377
    size_policy()->ms_collection_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2378
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2379
  COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2381
  HandleMark hm;  // Discard invalid handles created during verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2382
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2383
  if (VerifyBeforeGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2386
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2387
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  2388
  // Snapshot the soft reference policy to be used in this collection cycle.
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  2389
  ref_processor()->snap_policy(clear_all_soft_refs);
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  2390
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
  bool init_mark_was_synchronous = false; // until proven otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
  while (_collectorState != Idling) {
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 " in 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
    switch (_collectorState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
      case InitialMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
        init_mark_was_synchronous = true;  // fact to be exploited in re-mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
        checkpointRootsInitial(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
        assert(_collectorState == Marking, "Collector state should have changed"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
          " within checkpointRootsInitial()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
      case Marking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
        // initial marking in checkpointRootsInitialWork has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
          gclog_or_tty->print("Verify before initial mark: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2409
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2410
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2411
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2412
          bool res = markFromRoots(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
          assert(res && _collectorState == FinalMarking, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
            "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
      case FinalMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
          gclog_or_tty->print("Verify before re-mark: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
        checkpointRootsFinal(false, clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
                             init_mark_was_synchronous);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
        assert(_collectorState == Sweeping, "Collector state should not "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
          "have changed within checkpointRootsFinal()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
      case Sweeping:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
        // final marking in checkpointRootsFinal has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2431
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2432
          gclog_or_tty->print("Verify before sweep: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2433
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2434
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2435
        sweep(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2436
        assert(_collectorState == Resizing, "Incorrect state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2437
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2438
      case Resizing: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2439
        // Sweeping has been completed; the actual resize in this case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2440
        // is done separately; nothing to be done in this state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2441
        _collectorState = Resetting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2442
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2443
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2444
      case Resetting:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2445
        // The heap has been resized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2446
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2447
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2448
          gclog_or_tty->print("Verify before reset: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2449
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2450
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2451
        reset(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2452
        assert(_collectorState == Idling, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2453
          "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2454
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2455
      case Precleaning:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2456
      case AbortablePreclean:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2457
        // Elide the preclean phase
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2458
        _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2459
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2460
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2461
        ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2462
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2463
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2464
      gclog_or_tty->print_cr("  Thread " INTPTR_FORMAT " done - next CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2465
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2466
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2467
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2468
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2469
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2470
    GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2471
    size_policy()->ms_collection_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2472
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2473
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2474
  if (VerifyAfterGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2475
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2476
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2477
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2478
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2479
    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2480
      " exiting collection CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2481
      Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2482
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2483
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2484
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2485
bool CMSCollector::waitForForegroundGC() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2486
  bool res = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2487
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2488
         "CMS thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2489
  // Block the foreground collector until the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2490
  // background collectors decides whether to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2491
  // yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2492
  MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2493
  _foregroundGCShouldWait = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2494
  if (_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2495
    // The background collector yields to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2496
    // foreground collector and returns a value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2497
    // indicating that it has yielded.  The foreground
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2498
    // collector can proceed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2499
    res = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2500
    _foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2501
    ConcurrentMarkSweepThread::clear_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2502
      ConcurrentMarkSweepThread::CMS_cms_has_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2503
    ConcurrentMarkSweepThread::set_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2504
      ConcurrentMarkSweepThread::CMS_cms_wants_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2505
    // Get a possibly blocked foreground thread going
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2506
    CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2507
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2508
      gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT " waiting at CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2509
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2510
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2511
    while (_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
      CGC_lock->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2513
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2514
    ConcurrentMarkSweepThread::set_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2515
      ConcurrentMarkSweepThread::CMS_cms_has_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2516
    ConcurrentMarkSweepThread::clear_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
      ConcurrentMarkSweepThread::CMS_cms_wants_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2519
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT " continuing at CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2521
      Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2524
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2525
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2526
// Because of the need to lock the free lists and other structures in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
// the collector, common to all the generations that the collector is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2528
// collecting, we need the gc_prologues of individual CMS generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2529
// delegate to their collector. It may have been simpler had the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
// current infrastructure allowed one to call a prologue on a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2531
// collector. In the absence of that we have the generation's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
// prologue delegate to the collector, which delegates back
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2533
// some "local" work to a worker method in the individual generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2534
// that it's responsible for collecting, while itself doing any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2535
// work common to all generations it's responsible for. A similar
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2536
// comment applies to the  gc_epilogue()'s.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2537
// The role of the varaible _between_prologue_and_epilogue is to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
// enforce the invocation protocol.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
void CMSCollector::gc_prologue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2540
  // Call gc_prologue_work() for each CMSGen and PermGen that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
  // we are responsible for.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
  // The following locking discipline assumes that we are only called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
  // when the world is stopped.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
  assert(SafepointSynchronize::is_at_safepoint(), "world is stopped assumption");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
  // The CMSCollector prologue must call the gc_prologues for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
  // "generations" (including PermGen if any) that it's responsible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
  // for.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2551
  assert(   Thread::current()->is_VM_thread()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2552
         || (   CMSScavengeBeforeRemark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2553
             && Thread::current()->is_ConcurrentGC_thread()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
         "Incorrect thread type for prologue execution");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2556
  if (_between_prologue_and_epilogue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2557
    // We have already been invoked; this is a gc_prologue delegation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2558
    // from yet another CMS generation that we are responsible for, just
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2559
    // ignore it since all relevant work has already been done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2560
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2561
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
  // set a bit saying prologue has been called; cleared in epilogue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2564
  _between_prologue_and_epilogue = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2565
  // Claim locks for common data structures, then call gc_prologue_work()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2566
  // for each CMSGen and PermGen that we are responsible for.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2567
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2568
  getFreelistLocks();   // gets free list locks on constituent spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2569
  bitMapLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2570
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2571
  // Should call gc_prologue_work() for all cms gens we are responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2572
  bool registerClosure =    _collectorState >= Marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2573
                         && _collectorState < Sweeping;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2574
  ModUnionClosure* muc = ParallelGCThreads > 0 ? &_modUnionClosurePar
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
                                               : &_modUnionClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2576
  _cmsGen->gc_prologue_work(full, registerClosure, muc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
  _permGen->gc_prologue_work(full, registerClosure, muc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2579
  if (!full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2580
    stats().record_gc0_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
void ConcurrentMarkSweepGeneration::gc_prologue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
  // Delegate to CMScollector which knows how to coordinate between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
  // this and any other CMS generations that it is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
  // collecting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
  collector()->gc_prologue(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2590
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2591
// This is a "private" interface for use by this generation's CMSCollector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2592
// Not to be called directly by any other entity (for instance,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2593
// GenCollectedHeap, which calls the "public" gc_prologue method above).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2594
void ConcurrentMarkSweepGeneration::gc_prologue_work(bool full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
  bool registerClosure, ModUnionClosure* modUnionClosure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
  assert(!incremental_collection_failed(), "Shouldn't be set yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
  assert(cmsSpace()->preconsumptionDirtyCardClosure() == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
    "Should be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
  if (registerClosure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
    cmsSpace()->setPreconsumptionDirtyCardClosure(modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
  cmsSpace()->gc_prologue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
  // Clear stat counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2604
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
    assert(_numObjectsPromoted == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
    assert(_numWordsPromoted   == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
      gclog_or_tty->print("Allocated "SIZE_FORMAT" objects, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
                          SIZE_FORMAT" bytes concurrently",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2610
      _numObjectsAllocated, _numWordsAllocated*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
    _numObjectsAllocated = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2613
    _numWordsAllocated   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2614
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2615
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2616
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2617
void CMSCollector::gc_epilogue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2618
  // The following locking discipline assumes that we are only called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2619
  // when the world is stopped.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2620
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2621
         "world is stopped assumption");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2622
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2623
  // Currently the CMS epilogue (see CompactibleFreeListSpace) merely checks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
  // if linear allocation blocks need to be appropriately marked to allow the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
  // the blocks to be parsable. We also check here whether we need to nudge the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2626
  // CMS collector thread to start a new cycle (if it's not already active).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
  assert(   Thread::current()->is_VM_thread()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2628
         || (   CMSScavengeBeforeRemark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2629
             && Thread::current()->is_ConcurrentGC_thread()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2630
         "Incorrect thread type for epilogue execution");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2631
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
  if (!_between_prologue_and_epilogue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2633
    // We have already been invoked; this is a gc_epilogue delegation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2634
    // from yet another CMS generation that we are responsible for, just
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2635
    // ignore it since all relevant work has already been done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2636
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2637
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2638
  assert(haveFreelistLocks(), "must have freelist locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2639
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2640
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2641
  _cmsGen->gc_epilogue_work(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2642
  _permGen->gc_epilogue_work(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2643
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2644
  if (_collectorState == AbortablePreclean || _collectorState == Precleaning) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2645
    // in case sampling was not already enabled, enable it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2646
    _start_sampling = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2647
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2648
  // reset _eden_chunk_array so sampling starts afresh
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2649
  _eden_chunk_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2650
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2651
  size_t cms_used   = _cmsGen->cmsSpace()->used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2652
  size_t perm_used  = _permGen->cmsSpace()->used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2653
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2654
  // update performance counters - this uses a special version of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2655
  // update_counters() that allows the utilization to be passed as a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2656
  // parameter, avoiding multiple calls to used().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2657
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2658
  _cmsGen->update_counters(cms_used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2659
  _permGen->update_counters(perm_used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2660
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2661
  if (CMSIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2662
    icms_update_allocation_limits();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2663
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2664
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2665
  bitMapLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2666
  releaseFreelistLocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2667
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2668
  _between_prologue_and_epilogue = false;  // ready for next cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2669
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2670
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2671
void ConcurrentMarkSweepGeneration::gc_epilogue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2672
  collector()->gc_epilogue(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2673
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2674
  // Also reset promotion tracking in par gc thread states.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2675
  if (ParallelGCThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2676
    for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2677
      _par_gc_thread_states[i]->promo.stopTrackingPromotions();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2678
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2679
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2680
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2681
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2682
void ConcurrentMarkSweepGeneration::gc_epilogue_work(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2683
  assert(!incremental_collection_failed(), "Should have been cleared");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2684
  cmsSpace()->setPreconsumptionDirtyCardClosure(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2685
  cmsSpace()->gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2686
    // Print stat counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2687
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2688
    assert(_numObjectsAllocated == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2689
    assert(_numWordsAllocated == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2690
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2691
      gclog_or_tty->print("Promoted "SIZE_FORMAT" objects, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2692
                          SIZE_FORMAT" bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2693
                 _numObjectsPromoted, _numWordsPromoted*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2694
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2695
    _numObjectsPromoted = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2696
    _numWordsPromoted   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2697
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2698
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2699
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2700
    // Call down the chain in contiguous_available needs the freelistLock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2701
    // so print this out before releasing the freeListLock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2702
    gclog_or_tty->print(" Contiguous available "SIZE_FORMAT" bytes ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2703
                        contiguous_available());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2704
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2705
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2706
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2707
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2708
bool CMSCollector::have_cms_token() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2709
  Thread* thr = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2710
  if (thr->is_VM_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2711
    return ConcurrentMarkSweepThread::vm_thread_has_cms_token();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2712
  } else if (thr->is_ConcurrentGC_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2713
    return ConcurrentMarkSweepThread::cms_thread_has_cms_token();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2714
  } else if (thr->is_GC_task_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2715
    return ConcurrentMarkSweepThread::vm_thread_has_cms_token() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2716
           ParGCRareEvent_lock->owned_by_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2717
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2718
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2719
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2720
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2721
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2722
// Check reachability of the given heap address in CMS generation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2723
// treating all other generations as roots.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2724
bool CMSCollector::is_cms_reachable(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2725
  // We could "guarantee" below, rather than assert, but i'll
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2726
  // leave these as "asserts" so that an adventurous debugger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2727
  // could try this in the product build provided some subset of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2728
  // the conditions were met, provided they were intersted in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2729
  // results and knew that the computation below wouldn't interfere
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2730
  // with other concurrent computations mutating the structures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2731
  // being read or written.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2732
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2733
         "Else mutations in object graph will make answer suspect");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2734
  assert(have_cms_token(), "Should hold cms token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2735
  assert(haveFreelistLocks(), "must hold free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2736
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2737
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2738
  // Clear the marking bit map array before starting, but, just
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2739
  // for kicks, first report if the given address is already marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2740
  gclog_or_tty->print_cr("Start: Address 0x%x is%s marked", addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2741
                _markBitMap.isMarked(addr) ? "" : " not");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2742
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2743
  if (verify_after_remark()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2744
    MutexLockerEx x(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2745
    bool result = verification_mark_bm()->isMarked(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2746
    gclog_or_tty->print_cr("TransitiveMark: Address 0x%x %s marked", addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2747
                           result ? "IS" : "is NOT");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2748
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2749
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2750
    gclog_or_tty->print_cr("Could not compute result");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2751
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2752
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2753
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2754
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2755
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2756
// CMS Verification Support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2757
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2758
// Following the remark phase, the following invariant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2759
// should hold -- each object in the CMS heap which is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2760
// marked in markBitMap() should be marked in the verification_mark_bm().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2761
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2762
class VerifyMarkedClosure: public BitMapClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2763
  CMSBitMap* _marks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2764
  bool       _failed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2765
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2766
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2767
  VerifyMarkedClosure(CMSBitMap* bm): _marks(bm), _failed(false) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2768
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  2769
  bool do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2770
    HeapWord* addr = _marks->offsetToHeapWord(offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2771
    if (!_marks->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2772
      oop(addr)->print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2773
      gclog_or_tty->print_cr(" ("INTPTR_FORMAT" should have been marked)", addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2774
      _failed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2775
    }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  2776
    return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2777
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2778
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2779
  bool failed() { return _failed; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2780
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2781
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2782
bool CMSCollector::verify_after_remark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2783
  gclog_or_tty->print(" [Verifying CMS Marking... ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2784
  MutexLockerEx ml(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2785
  static bool init = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2786
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2787
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2788
         "Else mutations in object graph will make answer suspect");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2789
  assert(have_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2790
         "Else there may be mutual interference in use of "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2791
         " verification data structures");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2792
  assert(_collectorState > Marking && _collectorState <= Sweeping,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2793
         "Else marking info checked here may be obsolete");
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
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2798
  // Allocate marking bit map if not already allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2799
  if (!init) { // first time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2800
    if (!verification_mark_bm()->allocate(_span)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2801
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2802
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2803
    init = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2804
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2805
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2806
  assert(verification_mark_stack()->isEmpty(), "Should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2807
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2808
  // Turn off refs discovery -- so we will be tracing through refs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2809
  // This is as intended, because by this time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2810
  // GC must already have cleared any refs that need to be cleared,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2811
  // and traced those that need to be marked; moreover,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2812
  // the marking done here is not going to intefere in any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2813
  // way with the marking information used by GC.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2814
  NoRefDiscovery no_discovery(ref_processor());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2815
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2816
  COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2817
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2818
  // Clear any marks from a previous round
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2819
  verification_mark_bm()->clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2820
  assert(verification_mark_stack()->isEmpty(), "markStack should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2821
  assert(overflow_list_is_empty(), "overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2822
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2823
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2824
  gch->ensure_parsability(false);  // fill TLABs, but no need to retire them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2825
  // Update the saved marks which may affect the root scans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2826
  gch->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2827
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2828
  if (CMSRemarkVerifyVariant == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2829
    // In this first variant of verification, we complete
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2830
    // all marking, then check if the new marks-verctor is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2831
    // a subset of the CMS marks-vector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2832
    verify_after_remark_work_1();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2833
  } else if (CMSRemarkVerifyVariant == 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2834
    // In this second variant of verification, we flag an error
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2835
    // (i.e. an object reachable in the new marks-vector not reachable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2836
    // in the CMS marks-vector) immediately, also indicating the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2837
    // identify of an object (A) that references the unmarked object (B) --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2838
    // presumably, a mutation to A failed to be picked up by preclean/remark?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2839
    verify_after_remark_work_2();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2840
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2841
    warning("Unrecognized value %d for CMSRemarkVerifyVariant",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2842
            CMSRemarkVerifyVariant);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2843
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2844
  gclog_or_tty->print(" done] ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2845
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2846
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2847
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2848
void CMSCollector::verify_after_remark_work_1() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2849
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2850
  HandleMark  hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2851
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2852
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2853
  // Mark from roots one level into CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2854
  MarkRefsIntoClosure notOlder(_span, verification_mark_bm(), true /* nmethods */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2855
  gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2856
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2857
  gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2858
                                true,   // younger gens are roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2859
                                true,   // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2860
                                SharedHeap::ScanningOption(roots_scanning_options()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2861
                                NULL, &notOlder);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2862
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2863
  // Now mark from the roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2864
  assert(_revisitStack.isEmpty(), "Should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2865
  MarkFromRootsClosure markFromRootsClosure(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2866
    verification_mark_bm(), verification_mark_stack(), &_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2867
    false /* don't yield */, true /* verifying */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2868
  assert(_restart_addr == NULL, "Expected pre-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2869
  verification_mark_bm()->iterate(&markFromRootsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2870
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2871
    // Deal with stack overflow: by restarting at the indicated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2872
    // address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2873
    HeapWord* ra = _restart_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2874
    markFromRootsClosure.reset(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2875
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2876
    verification_mark_bm()->iterate(&markFromRootsClosure, ra, _span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2877
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2878
  assert(verification_mark_stack()->isEmpty(), "Should have been drained");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2879
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2880
  // Should reset the revisit stack above, since no class tree
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2881
  // surgery is forthcoming.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2882
  _revisitStack.reset(); // throwing away all contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2883
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2884
  // Marking completed -- now verify that each bit marked in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2885
  // verification_mark_bm() is also marked in markBitMap(); flag all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2886
  // errors by printing corresponding objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2887
  VerifyMarkedClosure vcl(markBitMap());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2888
  verification_mark_bm()->iterate(&vcl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2889
  if (vcl.failed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2890
    gclog_or_tty->print("Verification failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2891
    Universe::heap()->print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2892
    fatal(" ... aborting");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2893
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2894
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2895
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2896
void CMSCollector::verify_after_remark_work_2() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2897
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2898
  HandleMark  hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2899
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2900
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2901
  // Mark from roots one level into CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2902
  MarkRefsIntoVerifyClosure notOlder(_span, verification_mark_bm(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2903
                                     markBitMap(), true /* nmethods */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2904
  gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2905
  gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2906
                                true,   // younger gens are roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2907
                                true,   // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2908
                                SharedHeap::ScanningOption(roots_scanning_options()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2909
                                NULL, &notOlder);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2910
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2911
  // Now mark from the roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2912
  assert(_revisitStack.isEmpty(), "Should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2913
  MarkFromRootsVerifyClosure markFromRootsClosure(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2914
    verification_mark_bm(), markBitMap(), verification_mark_stack());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2915
  assert(_restart_addr == NULL, "Expected pre-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2916
  verification_mark_bm()->iterate(&markFromRootsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2917
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2918
    // Deal with stack overflow: by restarting at the indicated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2919
    // address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2920
    HeapWord* ra = _restart_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2921
    markFromRootsClosure.reset(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2922
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2923
    verification_mark_bm()->iterate(&markFromRootsClosure, ra, _span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2924
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2925
  assert(verification_mark_stack()->isEmpty(), "Should have been drained");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2926
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2927
  // Should reset the revisit stack above, since no class tree
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2928
  // surgery is forthcoming.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2929
  _revisitStack.reset(); // throwing away all contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2930
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2931
  // Marking completed -- now verify that each bit marked in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2932
  // verification_mark_bm() is also marked in markBitMap(); flag all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2933
  // errors by printing corresponding objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2934
  VerifyMarkedClosure vcl(markBitMap());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2935
  verification_mark_bm()->iterate(&vcl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2936
  assert(!vcl.failed(), "Else verification above should not have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2937
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2938
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2939
void ConcurrentMarkSweepGeneration::save_marks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2940
  // delegate to CMS space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2941
  cmsSpace()->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2942
  for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2943
    _par_gc_thread_states[i]->promo.startTrackingPromotions();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2944
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2945
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2946
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2947
bool ConcurrentMarkSweepGeneration::no_allocs_since_save_marks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2948
  return cmsSpace()->no_allocs_since_save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2949
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2950
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2951
#define CMS_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix)    \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2952
                                                                \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2953
void ConcurrentMarkSweepGeneration::                            \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2954
oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) {   \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2955
  cl->set_generation(this);                                     \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2956
  cmsSpace()->oop_since_save_marks_iterate##nv_suffix(cl);      \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2957
  cl->reset_generation();                                       \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2958
  save_marks();                                                 \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2959
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2960
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2961
ALL_SINCE_SAVE_MARKS_CLOSURES(CMS_SINCE_SAVE_MARKS_DEFN)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2962
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2963
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2964
ConcurrentMarkSweepGeneration::object_iterate_since_last_GC(ObjectClosure* blk)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2965
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2966
  // Not currently implemented; need to do the following. -- ysr.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2967
  // dld -- I think that is used for some sort of allocation profiler.  So it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2968
  // really means the objects allocated by the mutator since the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2969
  // GC.  We could potentially implement this cheaply by recording only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2970
  // the direct allocations in a side data structure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2971
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2972
  // I think we probably ought not to be required to support these
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2973
  // iterations at any arbitrary point; I think there ought to be some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2974
  // call to enable/disable allocation profiling in a generation/space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2975
  // and the iterator ought to return the objects allocated in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2976
  // gen/space since the enable call, or the last iterator call (which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2977
  // will probably be at a GC.)  That way, for gens like CM&S that would
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2978
  // require some extra data structure to support this, we only pay the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2979
  // cost when it's in use...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2980
  cmsSpace()->object_iterate_since_last_GC(blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2981
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2982
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2983
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2984
ConcurrentMarkSweepGeneration::younger_refs_iterate(OopsInGenClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2985
  cl->set_generation(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2986
  younger_refs_in_space_iterate(_cmsSpace, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2987
  cl->reset_generation();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2988
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2989
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2990
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2991
ConcurrentMarkSweepGeneration::oop_iterate(MemRegion mr, OopClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2992
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2993
    Generation::oop_iterate(mr, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2994
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2995
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2996
    Generation::oop_iterate(mr, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2997
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2998
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2999
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3000
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3001
ConcurrentMarkSweepGeneration::oop_iterate(OopClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3002
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3003
    Generation::oop_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3004
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3005
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3006
    Generation::oop_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3007
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3008
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3009
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3010
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3011
ConcurrentMarkSweepGeneration::object_iterate(ObjectClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3012
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3013
    Generation::object_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3014
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3015
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3016
    Generation::object_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3017
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3018
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3019
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3020
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3021
ConcurrentMarkSweepGeneration::pre_adjust_pointers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3022
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3023
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3024
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3025
ConcurrentMarkSweepGeneration::post_compact() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3026
}
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::prepare_for_verify() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3030
  // Fix the linear allocation blocks to look like free blocks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3031
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3032
  // Locks are normally acquired/released in gc_prologue/gc_epilogue, but those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3033
  // are not called when the heap is verified during universe initialization and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3034
  // at vm shutdown.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3035
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3036
    cmsSpace()->prepare_for_verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3037
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3038
    MutexLockerEx fll(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3039
    cmsSpace()->prepare_for_verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3040
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3041
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3042
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3043
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3044
ConcurrentMarkSweepGeneration::verify(bool allow_dirty /* ignored */) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3045
  // Locks are normally acquired/released in gc_prologue/gc_epilogue, but those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3046
  // are not called when the heap is verified during universe initialization and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3047
  // at vm shutdown.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3048
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3049
    cmsSpace()->verify(false /* ignored */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3050
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3051
    MutexLockerEx fll(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3052
    cmsSpace()->verify(false /* ignored */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3053
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3054
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3055
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3056
void CMSCollector::verify(bool allow_dirty /* ignored */) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3057
  _cmsGen->verify(allow_dirty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3058
  _permGen->verify(allow_dirty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3059
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3060
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3061
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3062
bool CMSCollector::overflow_list_is_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3063
  assert(_num_par_pushes >= 0, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3064
  if (_overflow_list == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3065
    assert(_num_par_pushes == 0, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3066
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3067
  return _overflow_list == NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3068
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3069
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3070
// The methods verify_work_stacks_empty() and verify_overflow_empty()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3071
// merely consolidate assertion checks that appear to occur together frequently.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3072
void CMSCollector::verify_work_stacks_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3073
  assert(_markStack.isEmpty(), "Marking stack should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3074
  assert(overflow_list_is_empty(), "Overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3075
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3076
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3077
void CMSCollector::verify_overflow_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3078
  assert(overflow_list_is_empty(), "Overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3079
  assert(no_preserved_marks(), "No preserved marks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3080
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3081
#endif // PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3082
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3083
// 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
  3084
// 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
  3085
// unload classes if it's the case that:
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3086
// (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
  3087
//     ExplicitGCInvokesConcurrentAndUnloadsClasses is set, OR
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3088
// (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
  3089
//     (b) (i)   perm gen threshold has been crossed, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3090
//         (ii)  old gen is getting really full, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3091
//         (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
  3092
//               perm gen
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3093
// 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
  3094
// 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
  3095
// 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
  3096
// 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
  3097
// 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
  3098
// the property that concurrent_cycles_since_last_unload()
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3099
// 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
  3100
// _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
  3101
// themselves also monotonic in that sense. See check_monotonicity()
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3102
// below.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3103
bool CMSCollector::update_should_unload_classes() {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3104
  _should_unload_classes = false;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3105
  // Condition 1 above
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3106
  if (_full_gc_requested && ExplicitGCInvokesConcurrentAndUnloadsClasses) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3107
    _should_unload_classes = true;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3108
  } else if (CMSClassUnloadingEnabled) { // Condition 2.a above
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3109
    // Disjuncts 2.b.(i,ii,iii) above
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3110
    _should_unload_classes = (concurrent_cycles_since_last_unload() >=
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3111
                              CMSClassUnloadingMaxInterval)
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3112
                           || _permGen->should_concurrent_collect()
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3113
                           || _cmsGen->is_too_full();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3114
  }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3115
  return _should_unload_classes;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3116
}
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3117
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3118
bool ConcurrentMarkSweepGeneration::is_too_full() const {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3119
  bool res = should_concurrent_collect();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3120
  res = res && (occupancy() > (double)CMSIsTooFullPercentage/100.0);
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3121
  return res;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3122
}
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3123
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3124
void CMSCollector::setup_cms_unloading_and_verification_state() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3125
  const  bool should_verify =    VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3126
                             || VerifyBeforeExit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3127
  const  int  rso           =    SharedHeap::SO_Symbols | SharedHeap::SO_Strings
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3128
                             |   SharedHeap::SO_CodeCache;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3129
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3130
  if (should_unload_classes()) {   // Should unload classes this cycle
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3131
    remove_root_scanning_option(rso);  // Shrink the root set appropriately
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3132
    set_verifying(should_verify);    // Set verification state for this cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3133
    return;                            // Nothing else needs to be done at this time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3134
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3135
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3136
  // Not unloading classes this cycle
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3137
  assert(!should_unload_classes(), "Inconsitency!");
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3138
  if ((!verifying() || unloaded_classes_last_cycle()) && should_verify) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3139
    // We were not verifying, or we _were_ unloading classes in the last cycle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3140
    // AND some verification options are enabled this cycle; in this case,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3141
    // we must make sure that the deadness map is allocated if not already so,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3142
    // and cleared (if already allocated previously --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3143
    // CMSBitMap::sizeInBits() is used to determine if it's allocated).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3144
    if (perm_gen_verify_bit_map()->sizeInBits() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3145
      if (!perm_gen_verify_bit_map()->allocate(_permGen->reserved())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3146
        warning("Failed to allocate permanent generation verification CMS Bit Map;\n"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3147
                "permanent generation verification disabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3148
        return;  // Note that we leave verification disabled, so we'll retry this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3149
                 // allocation next cycle. We _could_ remember this failure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3150
                 // and skip further attempts and permanently disable verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3151
                 // attempts if that is considered more desirable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3152
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3153
      assert(perm_gen_verify_bit_map()->covers(_permGen->reserved()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3154
              "_perm_gen_ver_bit_map inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3155
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3156
      perm_gen_verify_bit_map()->clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3157
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3158
    // Include symbols, strings and code cache elements to prevent their resurrection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3159
    add_root_scanning_option(rso);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3160
    set_verifying(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3161
  } else if (verifying() && !should_verify) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3162
    // We were verifying, but some verification flags got disabled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3163
    set_verifying(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3164
    // Exclude symbols, strings and code cache elements from root scanning to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3165
    // reduce IM and RM pauses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3166
    remove_root_scanning_option(rso);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3167
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3168
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3169
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3170
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3171
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3172
HeapWord* CMSCollector::block_start(const void* p) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3173
  const HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3174
  if (_span.contains(p)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3175
    if (_cmsGen->cmsSpace()->is_in_reserved(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3176
      return _cmsGen->cmsSpace()->block_start(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3177
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3178
      assert(_permGen->cmsSpace()->is_in_reserved(addr),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3179
             "Inconsistent _span?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3180
      return _permGen->cmsSpace()->block_start(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3181
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3182
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3183
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3184
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3185
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3186
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3187
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3188
ConcurrentMarkSweepGeneration::expand_and_allocate(size_t word_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3189
                                                   bool   tlab,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3190
                                                   bool   parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3191
  assert(!tlab, "Can't deal with TLAB allocation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3192
  MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3193
  expand(word_size*HeapWordSize, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3194
    CMSExpansionCause::_satisfy_allocation);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3195
  if (GCExpandToAllocateDelayMillis > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3196
    os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3197
  }
182
eae79d9b9d46 6642634: Test nsk/regression/b6186200 crashed with SIGSEGV
ysr
parents: 180
diff changeset
  3198
  return have_lock_and_allocate(word_size, tlab);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3199
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3200
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3201
// YSR: All of this generation expansion/shrinking stuff is an exact copy of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3202
// OneContigSpaceCardGeneration, which makes me wonder if we should move this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3203
// to CardGeneration and share it...
979
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3204
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
  3205
  return CardGeneration::expand(bytes, expand_bytes);
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3206
}
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3207
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3208
void ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3209
  CMSExpansionCause::Cause cause)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3210
{
979
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3211
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3212
  bool success = expand(bytes, expand_bytes);
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3213
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3214
  // remember why we expanded; this information is used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3215
  // by shouldConcurrentCollect() when making decisions on whether to start
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3216
  // a new CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3217
  if (success) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3218
    set_expansion_cause(cause);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3219
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3220
      gclog_or_tty->print_cr("Expanded CMS gen for %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3221
        CMSExpansionCause::to_string(cause));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3222
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3223
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3224
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3225
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3226
HeapWord* ConcurrentMarkSweepGeneration::expand_and_par_lab_allocate(CMSParGCThreadState* ps, size_t word_sz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3227
  HeapWord* res = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3228
  MutexLocker x(ParGCRareEvent_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3229
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3230
    // Expansion by some other thread might make alloc OK now:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3231
    res = ps->lab.alloc(word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3232
    if (res != NULL) return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3233
    // If there's not enough expansion space available, give up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3234
    if (_virtual_space.uncommitted_size() < (word_sz * HeapWordSize)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3235
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3236
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3237
    // Otherwise, we try expansion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3238
    expand(word_sz*HeapWordSize, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3239
      CMSExpansionCause::_allocate_par_lab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3240
    // Now go around the loop and try alloc again;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3241
    // A competing par_promote might beat us to the expansion space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3242
    // so we may go around the loop again if promotion fails agaion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3243
    if (GCExpandToAllocateDelayMillis > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3244
      os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3245
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3246
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3247
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3248
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3249
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3250
bool ConcurrentMarkSweepGeneration::expand_and_ensure_spooling_space(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3251
  PromotionInfo* promo) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3252
  MutexLocker x(ParGCRareEvent_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3253
  size_t refill_size_bytes = promo->refillSize() * HeapWordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3254
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3255
    // Expansion by some other thread might make alloc OK now:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3256
    if (promo->ensure_spooling_space()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3257
      assert(promo->has_spooling_space(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3258
             "Post-condition of successful ensure_spooling_space()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3259
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3260
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3261
    // If there's not enough expansion space available, give up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3262
    if (_virtual_space.uncommitted_size() < refill_size_bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3263
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3264
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3265
    // Otherwise, we try expansion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3266
    expand(refill_size_bytes, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3267
      CMSExpansionCause::_allocate_par_spooling_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3268
    // Now go around the loop and try alloc again;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3269
    // A competing allocation might beat us to the expansion space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3270
    // so we may go around the loop again if allocation fails again.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3271
    if (GCExpandToAllocateDelayMillis > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3272
      os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3273
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3274
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3275
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3276
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3277
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3278
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3279
void ConcurrentMarkSweepGeneration::shrink(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3280
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3281
  size_t size = ReservedSpace::page_align_size_down(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3282
  if (size > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3283
    shrink_by(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3284
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3285
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3286
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3287
bool ConcurrentMarkSweepGeneration::grow_by(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3288
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3289
  bool result = _virtual_space.expand_by(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3290
  if (result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3291
    HeapWord* old_end = _cmsSpace->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3292
    size_t new_word_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3293
      heap_word_size(_virtual_space.committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3294
    MemRegion mr(_cmsSpace->bottom(), new_word_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3295
    _bts->resize(new_word_size);  // resize the block offset shared array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3296
    Universe::heap()->barrier_set()->resize_covered_region(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3297
    // Hmmmm... why doesn't CFLS::set_end verify locking?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3298
    // This is quite ugly; FIX ME XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3299
    _cmsSpace->assert_locked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3300
    _cmsSpace->set_end((HeapWord*)_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3301
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3302
    // update the space and generation capacity counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3303
    if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3304
      _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3305
      _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3306
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3307
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3308
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3309
      size_t new_mem_size = _virtual_space.committed_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3310
      size_t old_mem_size = new_mem_size - bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3311
      gclog_or_tty->print_cr("Expanding %s from %ldK by %ldK to %ldK",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3312
                    name(), old_mem_size/K, bytes/K, new_mem_size/K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3313
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3314
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3315
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3316
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3317
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3318
bool ConcurrentMarkSweepGeneration::grow_to_reserved() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3319
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3320
  bool success = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3321
  const size_t remaining_bytes = _virtual_space.uncommitted_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3322
  if (remaining_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3323
    success = grow_by(remaining_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3324
    DEBUG_ONLY(if (!success) warning("grow to reserved failed");)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3325
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3326
  return success;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3327
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3328
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3329
void ConcurrentMarkSweepGeneration::shrink_by(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3330
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3331
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3332
  // XXX Fix when compaction is implemented.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3333
  warning("Shrinking of CMS not yet implemented");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3334
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3335
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3336
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3337
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3338
// Simple ctor/dtor wrapper for accounting & timer chores around concurrent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3339
// phases.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3340
class CMSPhaseAccounting: public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3341
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3342
  CMSPhaseAccounting(CMSCollector *collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3343
                     const char *phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3344
                     bool print_cr = true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3345
  ~CMSPhaseAccounting();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3346
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3347
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3348
  CMSCollector *_collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3349
  const char *_phase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3350
  elapsedTimer _wallclock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3351
  bool _print_cr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3352
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3353
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3354
  // Not MT-safe; so do not pass around these StackObj's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3355
  // where they may be accessed by other threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3356
  jlong wallclock_millis() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3357
    assert(_wallclock.is_active(), "Wall clock should not stop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3358
    _wallclock.stop();  // to record time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3359
    jlong ret = _wallclock.milliseconds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3360
    _wallclock.start(); // restart
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3361
    return ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3362
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3363
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3364
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3365
CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3366
                                       const char *phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3367
                                       bool print_cr) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3368
  _collector(collector), _phase(phase), _print_cr(print_cr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3369
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3370
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3371
    _collector->resetYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3372
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3373
  if (PrintGCDetails && PrintGCTimeStamps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3374
    gclog_or_tty->date_stamp(PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3375
    gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3376
    gclog_or_tty->print_cr(": [%s-concurrent-%s-start]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3377
      _collector->cmsGen()->short_name(), _phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3378
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3379
  _collector->resetTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3380
  _wallclock.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3381
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3382
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3383
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3384
CMSPhaseAccounting::~CMSPhaseAccounting() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3385
  assert(_wallclock.is_active(), "Wall clock should not have stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3386
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3387
  _wallclock.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3388
  if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3389
    gclog_or_tty->date_stamp(PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3390
    if (PrintGCTimeStamps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3391
      gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3392
      gclog_or_tty->print(": ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3393
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3394
    gclog_or_tty->print("[%s-concurrent-%s: %3.3f/%3.3f secs]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3395
                 _collector->cmsGen()->short_name(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3396
                 _phase, _collector->timerValue(), _wallclock.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3397
    if (_print_cr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3398
      gclog_or_tty->print_cr("");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3399
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3400
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3401
      gclog_or_tty->print_cr(" (CMS-concurrent-%s yielded %d times)", _phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3402
                    _collector->yields());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3403
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3404
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3405
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3406
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3407
// CMS work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3408
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3409
// Checkpoint the roots into this generation from outside
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3410
// this generation. [Note this initial checkpoint need only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3411
// be approximate -- we'll do a catch up phase subsequently.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3412
void CMSCollector::checkpointRootsInitial(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3413
  assert(_collectorState == InitialMarking, "Wrong collector state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3414
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3415
  ReferenceProcessor* rp = ref_processor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3416
  SpecializationStats::clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3417
  assert(_restart_addr == NULL, "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3418
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3419
    // acquire locks for subsequent manipulations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3420
    MutexLockerEx x(bitMapLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3421
                    Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3422
    checkpointRootsInitialWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3423
    rp->verify_no_references_recorded();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3424
    rp->enable_discovery(); // enable ("weak") refs discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3425
    _collectorState = Marking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3426
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3427
    // (Weak) Refs discovery: this is controlled from genCollectedHeap::do_collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3428
    // which recognizes if we are a CMS generation, and doesn't try to turn on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3429
    // discovery; verify that they aren't meddling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3430
    assert(!rp->discovery_is_atomic(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3431
           "incorrect setting of discovery predicate");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3432
    assert(!rp->discovery_enabled(), "genCollectedHeap shouldn't control "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3433
           "ref discovery for this generation kind");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3434
    // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3435
    checkpointRootsInitialWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3436
    rp->enable_discovery(); // now enable ("weak") refs discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3437
    _collectorState = Marking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3438
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3439
  SpecializationStats::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3440
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3441
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3442
void CMSCollector::checkpointRootsInitialWork(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3443
  assert(SafepointSynchronize::is_at_safepoint(), "world should be stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3444
  assert(_collectorState == InitialMarking, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3445
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3446
  // If there has not been a GC[n-1] since last GC[n] cycle completed,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3447
  // precede our marking with a collection of all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3448
  // younger generations to keep floating garbage to a minimum.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3449
  // XXX: we won't do this for now -- it's an optimization to be done later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3450
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3451
  // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3452
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3453
  assert(_markBitMap.isAllClear(), "was reset at end of previous cycle");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3454
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3455
  // Setup the verification and class unloading state for this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3456
  // CMS collection cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3457
  setup_cms_unloading_and_verification_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3458
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3459
  NOT_PRODUCT(TraceTime t("\ncheckpointRootsInitialWork",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3460
    PrintGCDetails && Verbose, true, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3461
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3462
    size_policy()->checkpoint_roots_initial_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3463
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3464
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3465
  // Reset all the PLAB chunk arrays if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3466
  if (_survivor_plab_array != NULL && !CMSPLABRecordAlways) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3467
    reset_survivor_plab_arrays();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3468
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3469
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3470
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3471
  HandleMark  hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3472
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3473
  FalseClosure falseClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3474
  // In the case of a synchronous collection, we will elide the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3475
  // remark step, so it's important to catch all the nmethod oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3476
  // in this step; hence the last argument to the constrcutor below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3477
  MarkRefsIntoClosure notOlder(_span, &_markBitMap, !asynch /* nmethods */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3478
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3479
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3480
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3481
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3482
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3483
  gch->ensure_parsability(false);  // fill TLABs, but no need to retire them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3484
  // Update the saved marks which may affect the root scans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3485
  gch->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3486
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3487
  // weak reference processing has not started yet.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3488
  ref_processor()->set_enqueuing_is_done(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3489
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3490
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3491
    COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3492
    gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3493
    gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3494
                                  true,   // younger gens are roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3495
                                  true,   // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3496
                                  SharedHeap::ScanningOption(roots_scanning_options()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3497
                                  NULL, &notOlder);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3498
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3499
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3500
  // Clear mod-union table; it will be dirtied in the prologue of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3501
  // CMS generation per each younger generation collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3502
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3503
  assert(_modUnionTable.isAllClear(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3504
       "Was cleared in most recent final checkpoint phase"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3505
       " or no bits are set in the gc_prologue before the start of the next "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3506
       "subsequent marking phase.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3507
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3508
  // Temporarily disabled, since pre/post-consumption closures don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3509
  // care about precleaned cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3510
  #if 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3511
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3512
    MemRegion mr = MemRegion((HeapWord*)_virtual_space.low(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3513
                             (HeapWord*)_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3514
    _ct->ct_bs()->preclean_dirty_cards(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3515
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3516
  #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3517
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3518
  // Save the end of the used_region of the constituent generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3519
  // to be used to limit the extent of sweep in each generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3520
  save_sweep_limits();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3521
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3522
    size_policy()->checkpoint_roots_initial_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3523
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3524
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3525
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3526
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3527
bool CMSCollector::markFromRoots(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3528
  // we might be tempted to assert that:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3529
  // assert(asynch == !SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3530
  //        "inconsistent argument?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3531
  // However that wouldn't be right, because it's possible that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3532
  // a safepoint is indeed in progress as a younger generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3533
  // stop-the-world GC happens even as we mark in this generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3534
  assert(_collectorState == Marking, "inconsistent state?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3535
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3536
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3537
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3538
  bool res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3539
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3540
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3541
    // Start the timers for adaptive size policy for the concurrent phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3542
    // Do it here so that the foreground MS can use the concurrent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3543
    // timer since a foreground MS might has the sweep done concurrently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3544
    // or STW.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3545
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3546
      size_policy()->concurrent_marking_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3547
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3548
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3549
    // Weak ref discovery note: We may be discovering weak
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3550
    // refs in this generation concurrent (but interleaved) with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3551
    // weak ref discovery by a younger generation collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3552
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3553
    CMSTokenSyncWithLocks ts(true, bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3554
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3555
    CMSPhaseAccounting pa(this, "mark", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3556
    res = markFromRootsWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3557
    if (res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3558
      _collectorState = Precleaning;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3559
    } else { // We failed and a foreground collection wants to take over
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3560
      assert(_foregroundGCIsActive, "internal state inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3561
      assert(_restart_addr == NULL,  "foreground will restart from scratch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3562
      if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3563
        gclog_or_tty->print_cr("bailing out to foreground collection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3564
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3565
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3566
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3567
      size_policy()->concurrent_marking_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3568
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3569
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3570
    assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3571
           "inconsistent with asynch == false");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3572
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3573
      size_policy()->ms_collection_marking_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3574
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3575
    // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3576
    res = markFromRootsWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3577
    _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3578
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3579
      GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3580
      size_policy()->ms_collection_marking_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3581
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3582
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3583
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3584
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3585
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3586
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3587
bool CMSCollector::markFromRootsWork(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3588
  // iterate over marked bits in bit map, doing a full scan and mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3589
  // from these roots using the following algorithm:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3590
  // . if oop is to the right of the current scan pointer,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3591
  //   mark corresponding bit (we'll process it later)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3592
  // . else (oop is to left of current scan pointer)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3593
  //   push oop on marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3594
  // . drain the marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3595
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3596
  // Note that when we do a marking step we need to hold the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3597
  // bit map lock -- recall that direct allocation (by mutators)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3598
  // and promotion (by younger generation collectors) is also
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3599
  // marking the bit map. [the so-called allocate live policy.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3600
  // Because the implementation of bit map marking is not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3601
  // robust wrt simultaneous marking of bits in the same word,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3602
  // we need to make sure that there is no such interference
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3603
  // between concurrent such updates.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3604
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3605
  // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3606
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3607
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3608
  // Clear the revisit stack, just in case there are any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3609
  // obsolete contents from a short-circuited previous CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3610
  _revisitStack.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3611
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3612
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3613
  assert(_revisitStack.isEmpty(), "tabula rasa");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3614
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3615
  bool result = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3616
  if (CMSConcurrentMTEnabled && ParallelCMSThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3617
    result = do_marking_mt(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3618
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3619
    result = do_marking_st(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3620
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3621
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3622
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3623
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3624
// Forward decl
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3625
class CMSConcMarkingTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3626
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3627
class CMSConcMarkingTerminator: public ParallelTaskTerminator {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3628
  CMSCollector*       _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3629
  CMSConcMarkingTask* _task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3630
  bool _yield;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3631
 protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3632
  virtual void yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3633
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3634
  // "n_threads" is the number of threads to be terminated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3635
  // "queue_set" is a set of work queues of other threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3636
  // "collector" is the CMS collector associated with this task terminator.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3637
  // "yield" indicates whether we need the gang as a whole to yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3638
  CMSConcMarkingTerminator(int n_threads, TaskQueueSetSuper* queue_set,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3639
                           CMSCollector* collector, bool yield) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3640
    ParallelTaskTerminator(n_threads, queue_set),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3641
    _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3642
    _yield(yield) { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3643
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3644
  void set_task(CMSConcMarkingTask* task) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3645
    _task = task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3646
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3647
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3648
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3649
// MT Concurrent Marking Task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3650
class CMSConcMarkingTask: public YieldingFlexibleGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3651
  CMSCollector* _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3652
  YieldingFlexibleWorkGang* _workers;        // the whole gang
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3653
  int           _n_workers;                  // requested/desired # workers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3654
  bool          _asynch;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3655
  bool          _result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3656
  CompactibleFreeListSpace*  _cms_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3657
  CompactibleFreeListSpace* _perm_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3658
  HeapWord*     _global_finger;
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3659
  HeapWord*     _restart_addr;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3660
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3661
  //  Exposed here for yielding support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3662
  Mutex* const _bit_map_lock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3663
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3664
  // The per thread work queues, available here for stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3665
  OopTaskQueueSet*  _task_queues;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3666
  CMSConcMarkingTerminator _term;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3667
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3668
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3669
  CMSConcMarkingTask(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3670
                 CompactibleFreeListSpace* cms_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3671
                 CompactibleFreeListSpace* perm_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3672
                 bool asynch, int n_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3673
                 YieldingFlexibleWorkGang* workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3674
                 OopTaskQueueSet* task_queues):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3675
    YieldingFlexibleGangTask("Concurrent marking done multi-threaded"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3676
    _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3677
    _cms_space(cms_space),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3678
    _perm_space(perm_space),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3679
    _asynch(asynch), _n_workers(n_workers), _result(true),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3680
    _workers(workers), _task_queues(task_queues),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3681
    _term(n_workers, task_queues, _collector, asynch),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3682
    _bit_map_lock(collector->bitMapLock())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3683
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3684
    assert(n_workers <= workers->total_workers(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3685
           "Else termination won't work correctly today"); // XXX FIX ME!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3686
    _requested_size = n_workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3687
    _term.set_task(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3688
    assert(_cms_space->bottom() < _perm_space->bottom(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3689
           "Finger incorrectly initialized below");
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3690
    _restart_addr = _global_finger = _cms_space->bottom();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3691
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3692
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3693
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3694
  OopTaskQueueSet* task_queues()  { return _task_queues; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3695
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3696
  OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3697
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3698
  HeapWord** global_finger_addr() { return &_global_finger; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3699
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3700
  CMSConcMarkingTerminator* terminator() { return &_term; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3701
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3702
  void work(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3703
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3704
  virtual void coordinator_yield();  // stuff done by coordinator
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3705
  bool result() { return _result; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3706
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3707
  void reset(HeapWord* ra) {
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3708
    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
  3709
    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
  3710
    assert(ra             <  _perm_space->end(), "ra too large");
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3711
    _restart_addr = _global_finger = ra;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3712
    _term.reset_for_reuse();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3713
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3714
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3715
  static bool get_work_from_overflow_stack(CMSMarkStack* ovflw_stk,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3716
                                           OopTaskQueue* work_q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3717
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3718
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3719
  void do_scan_and_mark(int i, CompactibleFreeListSpace* sp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3720
  void do_work_steal(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3721
  void bump_global_finger(HeapWord* f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3722
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3723
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3724
void CMSConcMarkingTerminator::yield() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3725
  if (ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3726
      !_collector->foregroundGCIsActive() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3727
      _yield) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3728
    _task->yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3729
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3730
    ParallelTaskTerminator::yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3731
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3732
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3733
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3734
////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3735
// Concurrent Marking Algorithm Sketch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3736
////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3737
// Until all tasks exhausted (both spaces):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3738
// -- claim next available chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3739
// -- bump global finger via CAS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3740
// -- find first object that starts in this chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3741
//    and start scanning bitmap from that position
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3742
// -- scan marked objects for oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3743
// -- CAS-mark target, and if successful:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3744
//    . if target oop is above global finger (volatile read)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3745
//      nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3746
//    . if target oop is in chunk and above local finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3747
//        then nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3748
//    . else push on work-queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3749
// -- Deal with possible overflow issues:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3750
//    . local work-queue overflow causes stuff to be pushed on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3751
//      global (common) overflow queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3752
//    . always first empty local work queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3753
//    . then get a batch of oops from global work queue if any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3754
//    . then do work stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3755
// -- When all tasks claimed (both spaces)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3756
//    and local work queue empty,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3757
//    then in a loop do:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3758
//    . check global overflow stack; steal a batch of oops and trace
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3759
//    . try to steal from other threads oif GOS is empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3760
//    . if neither is available, offer termination
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3761
// -- Terminate and return result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3762
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3763
void CMSConcMarkingTask::work(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3764
  elapsedTimer _timer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3765
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3766
  HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3767
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3768
  DEBUG_ONLY(_collector->verify_overflow_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3769
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3770
  // Before we begin work, our work queue should be empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3771
  assert(work_queue(i)->size() == 0, "Expected to be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3772
  // Scan the bitmap covering _cms_space, tracing through grey objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3773
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3774
  do_scan_and_mark(i, _cms_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3775
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3776
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3777
    gclog_or_tty->print_cr("Finished cms space scanning in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3778
      i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3779
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3780
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3781
  // ... do the same for the _perm_space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3782
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3783
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3784
  do_scan_and_mark(i, _perm_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3785
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3786
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3787
    gclog_or_tty->print_cr("Finished perm space scanning in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3788
      i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3789
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3790
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3791
  // ... do work stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3792
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3793
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3794
  do_work_steal(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3795
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3796
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3797
    gclog_or_tty->print_cr("Finished work stealing in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3798
      i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3799
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3800
  assert(_collector->_markStack.isEmpty(), "Should have been emptied");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3801
  assert(work_queue(i)->size() == 0, "Should have been emptied");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3802
  // Note that under the current task protocol, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3803
  // following assertion is true even of the spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3804
  // expanded since the completion of the concurrent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3805
  // marking. XXX This will likely change under a strict
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3806
  // ABORT semantics.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3807
  assert(_global_finger >  _cms_space->end() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3808
         _global_finger >= _perm_space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3809
         "All tasks have been completed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3810
  DEBUG_ONLY(_collector->verify_overflow_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3811
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3812
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3813
void CMSConcMarkingTask::bump_global_finger(HeapWord* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3814
  HeapWord* read = _global_finger;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3815
  HeapWord* cur  = read;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3816
  while (f > read) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3817
    cur = read;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3818
    read = (HeapWord*) Atomic::cmpxchg_ptr(f, &_global_finger, cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3819
    if (cur == read) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3820
      // our cas succeeded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3821
      assert(_global_finger >= f, "protocol consistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3822
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3823
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3824
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3825
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3826
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3827
// This is really inefficient, and should be redone by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3828
// using (not yet available) block-read and -write interfaces to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3829
// stack and the work_queue. XXX FIX ME !!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3830
bool CMSConcMarkingTask::get_work_from_overflow_stack(CMSMarkStack* ovflw_stk,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3831
                                                      OopTaskQueue* work_q) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3832
  // Fast lock-free check
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3833
  if (ovflw_stk->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3834
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3835
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3836
  assert(work_q->size() == 0, "Shouldn't steal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3837
  MutexLockerEx ml(ovflw_stk->par_lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3838
                   Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3839
  // Grab up to 1/4 the size of the work queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3840
  size_t num = MIN2((size_t)work_q->max_elems()/4,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3841
                    (size_t)ParGCDesiredObjsFromOverflowList);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3842
  num = MIN2(num, ovflw_stk->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3843
  for (int i = (int) num; i > 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3844
    oop cur = ovflw_stk->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3845
    assert(cur != NULL, "Counted wrong?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3846
    work_q->push(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3847
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3848
  return num > 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3849
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3850
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3851
void CMSConcMarkingTask::do_scan_and_mark(int i, CompactibleFreeListSpace* sp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3852
  SequentialSubTasksDone* pst = sp->conc_par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3853
  int n_tasks = pst->n_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3854
  // We allow that there may be no tasks to do here because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3855
  // we are restarting after a stack overflow.
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3856
  assert(pst->valid() || n_tasks == 0, "Uninitialized use?");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3857
  int nth_task = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3858
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3859
  HeapWord* aligned_start = sp->bottom();
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3860
  if (sp->used_region().contains(_restart_addr)) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3861
    // 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
  3862
    // for this space.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3863
    aligned_start =
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3864
      (HeapWord*)align_size_down((uintptr_t)_restart_addr,
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3865
                                 CardTableModRefBS::card_size);
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3866
  }
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3867
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3868
  size_t chunk_size = sp->marking_task_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3869
  while (!pst->is_task_claimed(/* reference */ nth_task)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3870
    // Having claimed the nth task in this space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3871
    // compute the chunk that it corresponds to:
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3872
    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
  3873
                               aligned_start + (nth_task+1)*chunk_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3874
    // Try and bump the global finger via a CAS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3875
    // note that we need to do the global finger bump
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3876
    // _before_ taking the intersection below, because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3877
    // the task corresponding to that region will be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3878
    // deemed done even if the used_region() expands
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3879
    // because of allocation -- as it almost certainly will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3880
    // during start-up while the threads yield in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3881
    // closure below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3882
    HeapWord* finger = span.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3883
    bump_global_finger(finger);   // atomically
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3884
    // There are null tasks here corresponding to chunks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3885
    // beyond the "top" address of the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3886
    span = span.intersection(sp->used_region());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3887
    if (!span.is_empty()) {  // Non-null task
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3888
      HeapWord* prev_obj;
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3889
      assert(!span.contains(_restart_addr) || nth_task == 0,
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3890
             "Inconsistency");
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3891
      if (nth_task == 0) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3892
        // 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
  3893
        if (span.contains(_restart_addr)) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3894
          // 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
  3895
          // we might additionally skip a chunk prefix.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3896
          prev_obj = _restart_addr;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3897
        } else {
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3898
          prev_obj = span.start();
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3899
        }
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3900
      } else {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3901
        // We want to skip the first object because
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3902
        // 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
  3903
        // that _starts_ in this span; a fortiori, any
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3904
        // object starting in an earlier span is scanned
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3905
        // as part of an earlier claimed task.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3906
        // 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
  3907
        // 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
  3908
        prev_obj = sp->block_start_careful(span.start());
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3909
        // 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
  3910
        // Printezis bits to avoid waiting for allocated
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3911
        // objects to become initialized/parsable.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3912
        while (prev_obj < span.start()) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3913
          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
  3914
          if (sz > 0) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3915
            prev_obj += sz;
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3916
          } else {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3917
            // 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
  3918
            // scanning, but that appears unavoidable, short of
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3919
            // locking the free list locks; see bug 6324141.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3920
            break;
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3921
          }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3922
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3923
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3924
      if (prev_obj < span.end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3925
        MemRegion my_span = MemRegion(prev_obj, span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3926
        // Do the marking work within a non-empty span --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3927
        // the last argument to the constructor indicates whether the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3928
        // iteration should be incremental with periodic yields.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3929
        Par_MarkFromRootsClosure cl(this, _collector, my_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3930
                                    &_collector->_markBitMap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3931
                                    work_queue(i),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3932
                                    &_collector->_markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3933
                                    &_collector->_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3934
                                    _asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3935
        _collector->_markBitMap.iterate(&cl, my_span.start(), my_span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3936
      } // else nothing to do for this task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3937
    }   // else nothing to do for this task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3938
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3939
  // We'd be tempted to assert here that since there are no
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3940
  // more tasks left to claim in this space, the global_finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3941
  // must exceed space->top() and a fortiori space->end(). However,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3942
  // that would not quite be correct because the bumping of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3943
  // global_finger occurs strictly after the claiming of a task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3944
  // so by the time we reach here the global finger may not yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3945
  // have been bumped up by the thread that claimed the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3946
  // task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3947
  pst->all_tasks_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3948
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3949
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3950
class Par_ConcMarkingClosure: public OopClosure {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  3951
 private:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3952
  CMSCollector* _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3953
  MemRegion     _span;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3954
  CMSBitMap*    _bit_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3955
  CMSMarkStack* _overflow_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3956
  CMSMarkStack* _revisit_stack;     // XXXXXX Check proper use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3957
  OopTaskQueue* _work_queue;
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  3958
 protected:
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  3959
  DO_OOP_WORK_DEFN
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3960
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3961
  Par_ConcMarkingClosure(CMSCollector* collector, OopTaskQueue* work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3962
                         CMSBitMap* bit_map, CMSMarkStack* overflow_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3963
    _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3964
    _span(_collector->_span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3965
    _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3966
    _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3967
    _overflow_stack(overflow_stack) { }   // need to initialize revisit stack etc.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  3968
  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
  3969
  virtual void do_oop(narrowOop* p);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3970
  void trim_queue(size_t max);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3971
  void handle_stack_overflow(HeapWord* lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3972
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3973
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3974
// Grey object scanning during work stealing phase --
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3975
// the salient assumption here is that any references
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3976
// 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
  3977
// 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
  3978
// 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
  3979
// 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
  3980
void Par_ConcMarkingClosure::do_oop(oop obj) {
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3981
  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
  3982
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3983
  // Check if oop points into the CMS generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3984
  // and is not marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3985
  if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3986
    // a white object ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3987
    // If we manage to "claim" the object, by being the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3988
    // first thread to mark it, then we push it on our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3989
    // marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3990
    if (_bit_map->par_mark(addr)) {     // ... now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3991
      // push on work queue (grey set)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3992
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3993
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3994
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3995
            _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3996
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3997
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3998
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3999
      )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4000
      if (simulate_overflow ||
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4001
          !(_work_queue->push(obj) || _overflow_stack->par_push(obj))) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4002
        // stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4003
        if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4004
          gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4005
                                 SIZE_FORMAT, _overflow_stack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4006
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4007
        // We cannot assert that the overflow stack is full because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4008
        // it may have been emptied since.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4009
        assert(simulate_overflow ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4010
               _work_queue->size() == _work_queue->max_elems(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4011
              "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4012
        handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4013
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4014
    } // Else, some other thread got there first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4015
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4016
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4017
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4018
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
  4019
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
  4020
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4021
void Par_ConcMarkingClosure::trim_queue(size_t max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4022
  while (_work_queue->size() > max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4023
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4024
    if (_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4025
      assert(new_oop->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4026
      assert(_bit_map->isMarked((HeapWord*)new_oop), "Grey object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4027
      assert(_span.contains((HeapWord*)new_oop), "Not in span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4028
      assert(new_oop->is_parsable(), "Should be parsable");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4029
      new_oop->oop_iterate(this);  // do_oop() above
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4030
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4031
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4032
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4033
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4034
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4035
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4036
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4037
void Par_ConcMarkingClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4038
  // 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
  4039
  // workers from interfering with the work done below.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4040
  MutexLockerEx ml(_overflow_stack->par_lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4041
                   Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4042
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4043
  HeapWord* ra = (HeapWord*)_overflow_stack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4044
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4045
  _overflow_stack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4046
  _overflow_stack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4047
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4048
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4049
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4050
void CMSConcMarkingTask::do_work_steal(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4051
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4052
  oop obj_to_scan;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4053
  CMSBitMap* bm = &(_collector->_markBitMap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4054
  CMSMarkStack* ovflw = &(_collector->_markStack);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4055
  int* seed = _collector->hash_seed(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4056
  Par_ConcMarkingClosure cl(_collector, work_q, bm, ovflw);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4057
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4058
    cl.trim_queue(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4059
    assert(work_q->size() == 0, "Should have been emptied above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4060
    if (get_work_from_overflow_stack(ovflw, work_q)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4061
      // Can't assert below because the work obtained from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4062
      // overflow stack may already have been stolen from us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4063
      // assert(work_q->size() > 0, "Work from overflow stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4064
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4065
    } else if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4066
      assert(obj_to_scan->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4067
      assert(bm->isMarked((HeapWord*)obj_to_scan), "Grey object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4068
      obj_to_scan->oop_iterate(&cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4069
    } else if (terminator()->offer_termination()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4070
      assert(work_q->size() == 0, "Impossible!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4071
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4072
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4073
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4074
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4075
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4076
// This is run by the CMS (coordinator) thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4077
void CMSConcMarkingTask::coordinator_yield() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4078
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4079
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4080
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4081
  // First give up the locks, then yield, then re-lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4082
  // We should probably use a constructor/destructor idiom to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4083
  // do this unlock/lock or modify the MutexUnlocker class to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4084
  // serve our purpose. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4085
  assert_lock_strong(_bit_map_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4086
  _bit_map_lock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4087
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4088
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4089
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4090
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4091
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4092
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4093
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4094
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4095
  // It is possible for whichever thread initiated the yield request
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4096
  // not to get a chance to wake up and take the bitmap lock between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4097
  // this thread releasing it and reacquiring it. So, while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4098
  // should_yield() flag is on, let's sleep for a bit to give the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4099
  // other thread a chance to wake up. The limit imposed on the number
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4100
  // of iterations is defensive, to avoid any unforseen circumstances
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4101
  // putting us into an infinite loop. Since it's always been this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4102
  // (coordinator_yield()) method that was observed to cause the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4103
  // problem, we are using a parameter (CMSCoordinatorYieldSleepCount)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4104
  // which is by default non-zero. For the other seven methods that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4105
  // also perform the yield operation, as are using a different
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4106
  // parameter (CMSYieldSleepCount) which is by default zero. This way we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4107
  // can enable the sleeping for those methods too, if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4108
  // See 6442774.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4109
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4110
  // We really need to reconsider the synchronization between the GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4111
  // thread and the yield-requesting threads in the future and we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4112
  // should really use wait/notify, which is the recommended
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4113
  // way of doing this type of interaction. Additionally, we should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4114
  // consolidate the eight methods that do the yield operation and they
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4115
  // are almost identical into one for better maintenability and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4116
  // readability. See 6445193.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4117
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4118
  // Tony 2006.06.29
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4119
  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
  4120
                   ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4121
                   !CMSCollector::foregroundGCIsActive(); ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4122
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4123
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4124
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4125
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4126
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4127
  _bit_map_lock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4128
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4129
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4130
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4131
bool CMSCollector::do_marking_mt(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4132
  assert(ParallelCMSThreads > 0 && conc_workers() != NULL, "precondition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4133
  // In the future this would be determined ergonomically, based
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4134
  // on #cpu's, # active mutator threads (and load), and mutation rate.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4135
  int num_workers = ParallelCMSThreads;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4136
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4137
  CompactibleFreeListSpace* cms_space  = _cmsGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4138
  CompactibleFreeListSpace* perm_space = _permGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4139
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4140
  CMSConcMarkingTask tsk(this, cms_space, perm_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4141
                         asynch, num_workers /* number requested XXX */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4142
                         conc_workers(), task_queues());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4143
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4144
  // Since the actual number of workers we get may be different
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4145
  // from the number we requested above, do we need to do anything different
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4146
  // below? In particular, may be we need to subclass the SequantialSubTasksDone
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4147
  // class?? XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4148
  cms_space ->initialize_sequential_subtasks_for_marking(num_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4149
  perm_space->initialize_sequential_subtasks_for_marking(num_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4150
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4151
  // Refs discovery is already non-atomic.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4152
  assert(!ref_processor()->discovery_is_atomic(), "Should be non-atomic");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4153
  // Mutate the Refs discovery so it is MT during the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4154
  // multi-threaded marking phase.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4155
  ReferenceProcessorMTMutator mt(ref_processor(), num_workers > 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4156
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4157
  conc_workers()->start_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4158
  while (tsk.yielded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4159
    tsk.coordinator_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4160
    conc_workers()->continue_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4161
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4162
  // If the task was aborted, _restart_addr will be non-NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4163
  assert(tsk.completed() || _restart_addr != NULL, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4164
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4165
    // XXX For now we do not make use of ABORTED state and have not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4166
    // yet implemented the right abort semantics (even in the original
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4167
    // single-threaded CMS case). That needs some more investigation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4168
    // and is deferred for now; see CR# TBF. 07252005YSR. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4169
    assert(!CMSAbortSemantics || tsk.aborted(), "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4170
    // If _restart_addr is non-NULL, a marking stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4171
    // occured; we need to do a fresh marking iteration from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4172
    // indicated restart address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4173
    if (_foregroundGCIsActive && asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4174
      // We may be running into repeated stack overflows, having
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4175
      // reached the limit of the stack size, while making very
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4176
      // slow forward progress. It may be best to bail out and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4177
      // let the foreground collector do its job.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4178
      // Clear _restart_addr, so that foreground GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4179
      // works from scratch. This avoids the headache of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4180
      // a "rescan" which would otherwise be needed because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4181
      // of the dirty mod union table & card table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4182
      _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4183
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4184
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4185
    // Adjust the task to restart from _restart_addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4186
    tsk.reset(_restart_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4187
    cms_space ->initialize_sequential_subtasks_for_marking(num_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4188
                  _restart_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4189
    perm_space->initialize_sequential_subtasks_for_marking(num_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4190
                  _restart_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4191
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4192
    // Get the workers going again
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4193
    conc_workers()->start_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4194
    while (tsk.yielded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4195
      tsk.coordinator_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4196
      conc_workers()->continue_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4197
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4198
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4199
  assert(tsk.completed(), "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4200
  assert(tsk.result() == true, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4201
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4202
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4203
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4204
bool CMSCollector::do_marking_st(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4205
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4206
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4207
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4208
  MarkFromRootsClosure markFromRootsClosure(this, _span, &_markBitMap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4209
    &_markStack, &_revisitStack, CMSYield && asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4210
  // the last argument to iterate indicates whether the iteration
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4211
  // should be incremental with periodic yields.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4212
  _markBitMap.iterate(&markFromRootsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4213
  // If _restart_addr is non-NULL, a marking stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4214
  // occured; we need to do a fresh iteration from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4215
  // indicated restart address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4216
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4217
    if (_foregroundGCIsActive && asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4218
      // We may be running into repeated stack overflows, having
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4219
      // reached the limit of the stack size, while making very
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4220
      // slow forward progress. It may be best to bail out and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4221
      // let the foreground collector do its job.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4222
      // Clear _restart_addr, so that foreground GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4223
      // works from scratch. This avoids the headache of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4224
      // a "rescan" which would otherwise be needed because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4225
      // of the dirty mod union table & card table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4226
      _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4227
      return false;  // indicating failure to complete marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4228
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4229
    // Deal with stack overflow:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4230
    // we restart marking from _restart_addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4231
    HeapWord* ra = _restart_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4232
    markFromRootsClosure.reset(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4233
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4234
    _markBitMap.iterate(&markFromRootsClosure, ra, _span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4235
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4236
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4237
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4238
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4239
void CMSCollector::preclean() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4240
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4241
  assert(Thread::current()->is_ConcurrentGC_thread(), "Wrong thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4242
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4243
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4244
  _abort_preclean = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4245
  if (CMSPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4246
    _eden_chunk_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4247
    size_t used = get_eden_used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4248
    size_t capacity = get_eden_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4249
    // Don't start sampling unless we will get sufficiently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4250
    // many samples.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4251
    if (used < (capacity/(CMSScheduleRemarkSamplingRatio * 100)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4252
                * CMSScheduleRemarkEdenPenetration)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4253
      _start_sampling = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4254
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4255
      _start_sampling = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4256
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4257
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4258
    CMSPhaseAccounting pa(this, "preclean", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4259
    preclean_work(CMSPrecleanRefLists1, CMSPrecleanSurvivors1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4260
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4261
  CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4262
  if (CMSPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4263
    sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4264
    _collectorState = AbortablePreclean;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4265
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4266
    _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4267
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4268
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4269
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4270
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4271
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4272
// Try and schedule the remark such that young gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4273
// occupancy is CMSScheduleRemarkEdenPenetration %.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4274
void CMSCollector::abortable_preclean() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4275
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4276
  assert(CMSPrecleaningEnabled,  "Inconsistent control state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4277
  assert(_collectorState == AbortablePreclean, "Inconsistent control state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4278
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4279
  // If Eden's current occupancy is below this threshold,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4280
  // immediately schedule the remark; else preclean
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4281
  // past the next scavenge in an effort to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4282
  // schedule the pause as described avove. By choosing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4283
  // CMSScheduleRemarkEdenSizeThreshold >= max eden size
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4284
  // we will never do an actual abortable preclean cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4285
  if (get_eden_used() > CMSScheduleRemarkEdenSizeThreshold) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4286
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4287
    CMSPhaseAccounting pa(this, "abortable-preclean", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4288
    // We need more smarts in the abortable preclean
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4289
    // loop below to deal with cases where allocation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4290
    // in young gen is very very slow, and our precleaning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4291
    // is running a losing race against a horde of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4292
    // mutators intent on flooding us with CMS updates
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4293
    // (dirty cards).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4294
    // One, admittedly dumb, strategy is to give up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4295
    // after a certain number of abortable precleaning loops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4296
    // or after a certain maximum time. We want to make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4297
    // this smarter in the next iteration.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4298
    // XXX FIX ME!!! YSR
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4299
    size_t loops = 0, workdone = 0, cumworkdone = 0, waited = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4300
    while (!(should_abort_preclean() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4301
             ConcurrentMarkSweepThread::should_terminate())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4302
      workdone = preclean_work(CMSPrecleanRefLists2, CMSPrecleanSurvivors2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4303
      cumworkdone += workdone;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4304
      loops++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4305
      // Voluntarily terminate abortable preclean phase if we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4306
      // been at it for too long.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4307
      if ((CMSMaxAbortablePrecleanLoops != 0) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4308
          loops >= CMSMaxAbortablePrecleanLoops) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4309
        if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4310
          gclog_or_tty->print(" CMS: abort preclean due to loops ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4311
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4312
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4313
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4314
      if (pa.wallclock_millis() > CMSMaxAbortablePrecleanTime) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4315
        if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4316
          gclog_or_tty->print(" CMS: abort preclean due to time ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4317
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4318
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4319
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4320
      // If we are doing little work each iteration, we should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4321
      // take a short break.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4322
      if (workdone < CMSAbortablePrecleanMinWorkPerIteration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4323
        // Sleep for some time, waiting for work to accumulate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4324
        stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4325
        cmsThread()->wait_on_cms_lock(CMSAbortablePrecleanWaitMillis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4326
        startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4327
        waited++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4328
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4329
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4330
    if (PrintCMSStatistics > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4331
      gclog_or_tty->print(" [%d iterations, %d waits, %d cards)] ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4332
                          loops, waited, cumworkdone);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4333
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4334
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4335
  CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4336
  if (_collectorState != Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4337
    assert(_collectorState == AbortablePreclean,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4338
           "Spontaneous state transition?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4339
    _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4340
  } // Else, a foreground collection completed this CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4341
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4342
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4343
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4344
// Respond to an Eden sampling opportunity
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4345
void CMSCollector::sample_eden() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4346
  // Make sure a young gc cannot sneak in between our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4347
  // reading and recording of a sample.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4348
  assert(Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4349
         "Only the cms thread may collect Eden samples");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4350
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4351
         "Should collect samples while holding CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4352
  if (!_start_sampling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4353
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4354
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4355
  if (_eden_chunk_array) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4356
    if (_eden_chunk_index < _eden_chunk_capacity) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4357
      _eden_chunk_array[_eden_chunk_index] = *_top_addr;   // take sample
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4358
      assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4359
             "Unexpected state of Eden");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4360
      // We'd like to check that what we just sampled is an oop-start address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4361
      // however, we cannot do that here since the object may not yet have been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4362
      // initialized. So we'll instead do the check when we _use_ this sample
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4363
      // later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4364
      if (_eden_chunk_index == 0 ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4365
          (pointer_delta(_eden_chunk_array[_eden_chunk_index],
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4366
                         _eden_chunk_array[_eden_chunk_index-1])
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4367
           >= CMSSamplingGrain)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4368
        _eden_chunk_index++;  // commit sample
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4369
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4370
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4371
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4372
  if ((_collectorState == AbortablePreclean) && !_abort_preclean) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4373
    size_t used = get_eden_used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4374
    size_t capacity = get_eden_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4375
    assert(used <= capacity, "Unexpected state of Eden");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4376
    if (used >  (capacity/100 * CMSScheduleRemarkEdenPenetration)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4377
      _abort_preclean = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4378
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4379
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4380
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4381
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4382
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4383
size_t CMSCollector::preclean_work(bool clean_refs, bool clean_survivor) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4384
  assert(_collectorState == Precleaning ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4385
         _collectorState == AbortablePreclean, "incorrect state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4386
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4387
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4388
  // Do one pass of scrubbing the discovered reference lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4389
  // to remove any reference objects with strongly-reachable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4390
  // referents.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4391
  if (clean_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4392
    ReferenceProcessor* rp = ref_processor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4393
    CMSPrecleanRefsYieldClosure yield_cl(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4394
    assert(rp->span().equals(_span), "Spans should be equal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4395
    CMSKeepAliveClosure keep_alive(this, _span, &_markBitMap,
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  4396
                                   &_markStack, true /* preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4397
    CMSDrainMarkingStackClosure complete_trace(this,
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  4398
                                   _span, &_markBitMap, &_markStack,
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  4399
                                   &keep_alive, true /* preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4400
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4401
    // We don't want this step to interfere with a young
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4402
    // collection because we don't want to take CPU
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4403
    // or memory bandwidth away from the young GC threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4404
    // (which may be as many as there are CPUs).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4405
    // Note that we don't need to protect ourselves from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4406
    // interference with mutators because they can't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4407
    // manipulate the discovered reference lists nor affect
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4408
    // the computed reachability of the referents, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4409
    // only properties manipulated by the precleaning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4410
    // of these reference lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4411
    stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4412
    CMSTokenSyncWithLocks x(true /* is cms thread */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4413
                            bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4414
    startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4415
    sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4416
    // The following will yield to allow foreground
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4417
    // collection to proceed promptly. XXX YSR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4418
    // The code in this method may need further
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4419
    // tweaking for better performance and some restructuring
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4420
    // for cleaner interfaces.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4421
    rp->preclean_discovered_references(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4422
          rp->is_alive_non_header(), &keep_alive, &complete_trace,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4423
          &yield_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4424
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4425
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4426
  if (clean_survivor) {  // preclean the active survivor space(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4427
    assert(_young_gen->kind() == Generation::DefNew ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4428
           _young_gen->kind() == Generation::ParNew ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4429
           _young_gen->kind() == Generation::ASParNew,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4430
         "incorrect type for cast");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4431
    DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4432
    PushAndMarkClosure pam_cl(this, _span, ref_processor(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4433
                             &_markBitMap, &_modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4434
                             &_markStack, &_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4435
                             true /* precleaning phase */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4436
    stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4437
    CMSTokenSyncWithLocks ts(true /* is cms thread */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4438
                             bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4439
    startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4440
    unsigned int before_count =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4441
      GenCollectedHeap::heap()->total_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4442
    SurvivorSpacePrecleanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4443
      sss_cl(this, _span, &_markBitMap, &_markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4444
             &pam_cl, before_count, CMSYield);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4445
    dng->from()->object_iterate_careful(&sss_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4446
    dng->to()->object_iterate_careful(&sss_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4447
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4448
  MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4449
    mrias_cl(_span, ref_processor(), &_markBitMap, &_modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4450
             &_markStack, &_revisitStack, this, CMSYield,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4451
             true /* precleaning phase */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4452
  // CAUTION: The following closure has persistent state that may need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4453
  // be reset upon a decrease in the sequence of addresses it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4454
  // processes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4455
  ScanMarkedObjectsAgainCarefullyClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4456
    smoac_cl(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4457
      &_markBitMap, &_markStack, &_revisitStack, &mrias_cl, CMSYield);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4458
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4459
  // Preclean dirty cards in ModUnionTable and CardTable using
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4460
  // appropriate convergence criterion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4461
  // repeat CMSPrecleanIter times unless we find that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4462
  // we are losing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4463
  assert(CMSPrecleanIter < 10, "CMSPrecleanIter is too large");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4464
  assert(CMSPrecleanNumerator < CMSPrecleanDenominator,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4465
         "Bad convergence multiplier");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4466
  assert(CMSPrecleanThreshold >= 100,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4467
         "Unreasonably low CMSPrecleanThreshold");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4468
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4469
  size_t numIter, cumNumCards, lastNumCards, curNumCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4470
  for (numIter = 0, cumNumCards = lastNumCards = curNumCards = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4471
       numIter < CMSPrecleanIter;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4472
       numIter++, lastNumCards = curNumCards, cumNumCards += curNumCards) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4473
    curNumCards  = preclean_mod_union_table(_cmsGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4474
    if (CMSPermGenPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4475
      curNumCards  += preclean_mod_union_table(_permGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4476
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4477
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4478
      gclog_or_tty->print(" (modUnionTable: %d cards)", curNumCards);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4479
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4480
    // Either there are very few dirty cards, so re-mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4481
    // pause will be small anyway, or our pre-cleaning isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4482
    // that much faster than the rate at which cards are being
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4483
    // dirtied, so we might as well stop and re-mark since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4484
    // precleaning won't improve our re-mark time by much.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4485
    if (curNumCards <= CMSPrecleanThreshold ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4486
        (numIter > 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4487
         (curNumCards * CMSPrecleanDenominator >
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4488
         lastNumCards * CMSPrecleanNumerator))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4489
      numIter++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4490
      cumNumCards += curNumCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4491
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4492
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4493
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4494
  curNumCards = preclean_card_table(_cmsGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4495
  if (CMSPermGenPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4496
    curNumCards += preclean_card_table(_permGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4497
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4498
  cumNumCards += curNumCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4499
  if (PrintGCDetails && PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4500
    gclog_or_tty->print_cr(" (cardTable: %d cards, re-scanned %d cards, %d iterations)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4501
                  curNumCards, cumNumCards, numIter);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4502
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4503
  return cumNumCards;   // as a measure of useful work done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4504
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4505
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4506
// PRECLEANING NOTES:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4507
// Precleaning involves:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4508
// . reading the bits of the modUnionTable and clearing the set bits.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4509
// . For the cards corresponding to the set bits, we scan the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4510
//   objects on those cards. This means we need the free_list_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4511
//   so that we can safely iterate over the CMS space when scanning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4512
//   for oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4513
// . When we scan the objects, we'll be both reading and setting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4514
//   marks in the marking bit map, so we'll need the marking bit map.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4515
// . For protecting _collector_state transitions, we take the CGC_lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4516
//   Note that any races in the reading of of card table entries by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4517
//   CMS thread on the one hand and the clearing of those entries by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4518
//   VM thread or the setting of those entries by the mutator threads on the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4519
//   other are quite benign. However, for efficiency it makes sense to keep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4520
//   the VM thread from racing with the CMS thread while the latter is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4521
//   dirty card info to the modUnionTable. We therefore also use the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4522
//   CGC_lock to protect the reading of the card table and the mod union
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4523
//   table by the CM thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4524
// . We run concurrently with mutator updates, so scanning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4525
//   needs to be done carefully  -- we should not try to scan
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4526
//   potentially uninitialized objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4527
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4528
// Locking strategy: While holding the CGC_lock, we scan over and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4529
// reset a maximal dirty range of the mod union / card tables, then lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4530
// the free_list_lock and bitmap lock to do a full marking, then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4531
// release these locks; and repeat the cycle. This allows for a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4532
// certain amount of fairness in the sharing of these locks between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4533
// the CMS collector on the one hand, and the VM thread and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4534
// mutators on the other.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4536
// NOTE: preclean_mod_union_table() and preclean_card_table()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4537
// further below are largely identical; if you need to modify
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4538
// one of these methods, please check the other method too.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4539
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4540
size_t CMSCollector::preclean_mod_union_table(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4541
  ConcurrentMarkSweepGeneration* gen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4542
  ScanMarkedObjectsAgainCarefullyClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4543
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4544
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4545
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4546
  // strategy: starting with the first card, accumulate contiguous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4547
  // ranges of dirty cards; clear these cards, then scan the region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4548
  // covered by these cards.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4549
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4550
  // Since all of the MUT is committed ahead, we can just use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4551
  // that, in case the generations expand while we are precleaning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4552
  // It might also be fine to just use the committed part of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4553
  // generation, but we might potentially miss cards when the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4554
  // generation is rapidly expanding while we are in the midst
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4555
  // of precleaning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4556
  HeapWord* startAddr = gen->reserved().start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4557
  HeapWord* endAddr   = gen->reserved().end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4558
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4559
  cl->setFreelistLock(gen->freelistLock());   // needed for yielding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4560
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4561
  size_t numDirtyCards, cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4562
  HeapWord *nextAddr, *lastAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4563
  for (cumNumDirtyCards = numDirtyCards = 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4564
       nextAddr = lastAddr = startAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4565
       nextAddr < endAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4566
       nextAddr = lastAddr, cumNumDirtyCards += numDirtyCards) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4567
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4568
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4569
    HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4570
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4571
    MemRegion dirtyRegion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4572
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4573
      stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4574
      CMSTokenSync ts(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4575
      startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4576
      sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4577
      // Get dirty region starting at nextOffset (inclusive),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4578
      // simultaneously clearing it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4579
      dirtyRegion =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4580
        _modUnionTable.getAndClearMarkedRegion(nextAddr, endAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4581
      assert(dirtyRegion.start() >= nextAddr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4582
             "returned region inconsistent?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4583
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4584
    // Remember where the next search should begin.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4585
    // The returned region (if non-empty) is a right open interval,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4586
    // so lastOffset is obtained from the right end of that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4587
    // interval.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4588
    lastAddr = dirtyRegion.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4589
    // Should do something more transparent and less hacky XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4590
    numDirtyCards =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4591
      _modUnionTable.heapWordDiffToOffsetDiff(dirtyRegion.word_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4592
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4593
    // We'll scan the cards in the dirty region (with periodic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4594
    // yields for foreground GC as needed).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4595
    if (!dirtyRegion.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4596
      assert(numDirtyCards > 0, "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4597
      HeapWord* stop_point = NULL;
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4598
      stopTimer();
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4599
      CMSTokenSyncWithLocks ts(true, gen->freelistLock(),
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4600
                               bitMapLock());
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4601
      startTimer();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4602
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4603
        verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4604
        verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4605
        sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4606
        stop_point =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4607
          gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4608
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4609
      if (stop_point != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4610
        // The careful iteration stopped early either because it found an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4611
        // uninitialized object, or because we were in the midst of an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4612
        // "abortable preclean", which should now be aborted. Redirty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4613
        // the bits corresponding to the partially-scanned or unscanned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4614
        // cards. We'll either restart at the next block boundary or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4615
        // abort the preclean.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4616
        assert((CMSPermGenPrecleaningEnabled && (gen == _permGen)) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4617
               (_collectorState == AbortablePreclean && should_abort_preclean()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4618
               "Unparsable objects should only be in perm gen.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4619
        _modUnionTable.mark_range(MemRegion(stop_point, dirtyRegion.end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4620
        if (should_abort_preclean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4621
          break; // out of preclean loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4622
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4623
          // Compute the next address at which preclean should pick up;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4624
          // might need bitMapLock in order to read P-bits.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4625
          lastAddr = next_card_start_after_block(stop_point);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4626
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4627
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4628
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4629
      assert(lastAddr == endAddr, "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4630
      assert(numDirtyCards == 0, "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4631
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4632
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4633
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4634
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4635
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4636
  return cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4637
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4638
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4639
// NOTE: preclean_mod_union_table() above and preclean_card_table()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4640
// below are largely identical; if you need to modify
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4641
// one of these methods, please check the other method too.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4642
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4643
size_t CMSCollector::preclean_card_table(ConcurrentMarkSweepGeneration* gen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4644
  ScanMarkedObjectsAgainCarefullyClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4645
  // strategy: it's similar to precleamModUnionTable above, in that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4646
  // we accumulate contiguous ranges of dirty cards, mark these cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4647
  // precleaned, then scan the region covered by these cards.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4648
  HeapWord* endAddr   = (HeapWord*)(gen->_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4649
  HeapWord* startAddr = (HeapWord*)(gen->_virtual_space.low());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4650
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4651
  cl->setFreelistLock(gen->freelistLock());   // needed for yielding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4652
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4653
  size_t numDirtyCards, cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4654
  HeapWord *lastAddr, *nextAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4655
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
      // See comments in "Precleaning notes" above on why we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4667
      // do this locking. XXX Could the locking overheads be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4668
      // too high when dirty cards are sparse? [I don't think so.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4669
      stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4670
      CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4671
      startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4672
      sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4673
      // Get and clear dirty region from card table
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4674
      dirtyRegion = _ct->ct_bs()->dirty_card_range_after_reset(
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4675
                                    MemRegion(nextAddr, endAddr),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4676
                                    true,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4677
                                    CardTableModRefBS::precleaned_card_val());
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4678
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4679
      assert(dirtyRegion.start() >= nextAddr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4680
             "returned region inconsistent?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4681
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4682
    lastAddr = dirtyRegion.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4683
    numDirtyCards =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4684
      dirtyRegion.word_size()/CardTableModRefBS::card_size_in_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4685
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4686
    if (!dirtyRegion.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4687
      stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4688
      CMSTokenSyncWithLocks ts(true, gen->freelistLock(), bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4689
      startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4690
      sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4691
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4692
      verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4693
      HeapWord* stop_point =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4694
        gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4695
      if (stop_point != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4696
        // The careful iteration stopped early because it found an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4697
        // uninitialized object.  Redirty the bits corresponding to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4698
        // partially-scanned or unscanned cards, and start again at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4699
        // next block boundary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4700
        assert(CMSPermGenPrecleaningEnabled ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4701
               (_collectorState == AbortablePreclean && should_abort_preclean()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4702
               "Unparsable objects should only be in perm gen.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4703
        _ct->ct_bs()->invalidate(MemRegion(stop_point, dirtyRegion.end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4704
        if (should_abort_preclean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4705
          break; // out of preclean loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4706
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4707
          // Compute the next address at which preclean should pick up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4708
          lastAddr = next_card_start_after_block(stop_point);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4709
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4710
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4711
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4712
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4713
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4714
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4715
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4716
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4717
  return cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4718
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4719
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4720
void CMSCollector::checkpointRootsFinal(bool asynch,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4721
  bool clear_all_soft_refs, bool init_mark_was_synchronous) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4722
  assert(_collectorState == FinalMarking, "incorrect state transition?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4723
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4724
  // world is stopped at this checkpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4725
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4726
         "world should be stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4727
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4728
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4729
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4730
  SpecializationStats::clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4731
  if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4732
    gclog_or_tty->print("[YG occupancy: "SIZE_FORMAT" K ("SIZE_FORMAT" K)]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4733
                        _young_gen->used() / K,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4734
                        _young_gen->capacity() / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4735
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4736
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4737
    if (CMSScavengeBeforeRemark) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4738
      GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4739
      // Temporarily set flag to false, GCH->do_collection will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4740
      // expect it to be false and set to true
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4741
      FlagSetting fl(gch->_is_gc_active, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4742
      NOT_PRODUCT(TraceTime t("Scavenge-Before-Remark",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4743
        PrintGCDetails && Verbose, true, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4744
      int level = _cmsGen->level() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4745
      if (level >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4746
        gch->do_collection(true,        // full (i.e. force, see below)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4747
                           false,       // !clear_all_soft_refs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4748
                           0,           // size
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4749
                           false,       // is_tlab
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4750
                           level        // max_level
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4751
                          );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4752
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4753
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4754
    FreelistLocker x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4755
    MutexLockerEx y(bitMapLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4756
                    Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4757
    assert(!init_mark_was_synchronous, "but that's impossible!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4758
    checkpointRootsFinalWork(asynch, clear_all_soft_refs, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4759
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4760
    // already have all the locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4761
    checkpointRootsFinalWork(asynch, clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4762
                             init_mark_was_synchronous);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4763
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4764
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4765
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4766
  SpecializationStats::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4767
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4768
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4769
void CMSCollector::checkpointRootsFinalWork(bool asynch,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4770
  bool clear_all_soft_refs, bool init_mark_was_synchronous) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4771
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4772
  NOT_PRODUCT(TraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4773
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4774
  assert(haveFreelistLocks(), "must have free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4775
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4776
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4777
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4778
    size_policy()->checkpoint_roots_final_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4779
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4780
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4781
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4782
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4784
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4785
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  4786
  if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4787
    CodeCache::gc_prologue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4788
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4789
  assert(haveFreelistLocks(), "must have free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4790
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4791
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4792
  if (!init_mark_was_synchronous) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4793
    // We might assume that we need not fill TLAB's when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4794
    // CMSScavengeBeforeRemark is set, because we may have just done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4795
    // a scavenge which would have filled all TLAB's -- and besides
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4796
    // Eden would be empty. This however may not always be the case --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4797
    // for instance although we asked for a scavenge, it may not have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4798
    // happened because of a JNI critical section. We probably need
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4799
    // a policy for deciding whether we can in that case wait until
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4800
    // the critical section releases and then do the remark following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4801
    // the scavenge, and skip it here. In the absence of that policy,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4802
    // or of an indication of whether the scavenge did indeed occur,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4803
    // we cannot rely on TLAB's having been filled and must do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4804
    // so here just in case a scavenge did not happen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4805
    gch->ensure_parsability(false);  // fill TLAB's, but no need to retire them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4806
    // Update the saved marks which may affect the root scans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4807
    gch->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4808
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4809
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4810
      COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4811
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4812
      // Note on the role of the mod union table:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4813
      // Since the marker in "markFromRoots" marks concurrently with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4814
      // mutators, it is possible for some reachable objects not to have been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4815
      // scanned. For instance, an only reference to an object A was
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4816
      // placed in object B after the marker scanned B. Unless B is rescanned,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4817
      // A would be collected. Such updates to references in marked objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4818
      // are detected via the mod union table which is the set of all cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4819
      // dirtied since the first checkpoint in this GC cycle and prior to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4820
      // the most recent young generation GC, minus those cleaned up by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4821
      // concurrent precleaning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4822
      if (CMSParallelRemarkEnabled && ParallelGCThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4823
        TraceTime t("Rescan (parallel) ", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4824
        do_remark_parallel();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4825
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4826
        TraceTime t("Rescan (non-parallel) ", PrintGCDetails, false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4827
                    gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4828
        do_remark_non_parallel();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4829
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4830
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4831
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4832
    assert(!asynch, "Can't have init_mark_was_synchronous in asynch mode");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4833
    // The initial mark was stop-world, so there's no rescanning to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4834
    // do; go straight on to the next step below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4835
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4836
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4837
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4838
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4839
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4840
    NOT_PRODUCT(TraceTime ts("refProcessingWork", PrintGCDetails, false, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4841
    refProcessingWork(asynch, clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4842
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4843
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4844
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4845
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  4846
  if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4847
    CodeCache::gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4848
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4849
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4850
  // If we encountered any (marking stack / work queue) overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4851
  // events during the current CMS cycle, take appropriate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4852
  // remedial measures, where possible, so as to try and avoid
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4853
  // recurrence of that condition.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4854
  assert(_markStack.isEmpty(), "No grey objects");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4855
  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
  4856
                     _ser_kac_ovflw        + _ser_kac_preclean_ovflw;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4857
  if (ser_ovflw > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4858
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4859
      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
  4860
        "(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
  4861
        ", kac_preclean="SIZE_FORMAT")",
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4862
        _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
  4863
        _ser_kac_ovflw, _ser_kac_preclean_ovflw);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4864
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4865
    _markStack.expand();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4866
    _ser_pmc_remark_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4867
    _ser_pmc_preclean_ovflw = 0;
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  4868
    _ser_kac_preclean_ovflw = 0;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4869
    _ser_kac_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4870
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4871
  if (_par_pmc_remark_ovflw > 0 || _par_kac_ovflw > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4872
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4873
      gclog_or_tty->print_cr("Work queue overflow (benign) "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4874
        "(pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT")",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4875
        _par_pmc_remark_ovflw, _par_kac_ovflw);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4876
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4877
    _par_pmc_remark_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4878
    _par_kac_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4879
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4880
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4881
     if (_markStack._hit_limit > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4882
       gclog_or_tty->print_cr(" (benign) Hit max stack size limit ("SIZE_FORMAT")",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4883
                              _markStack._hit_limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4884
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4885
     if (_markStack._failed_double > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4886
       gclog_or_tty->print_cr(" (benign) Failed stack doubling ("SIZE_FORMAT"),"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4887
                              " current capacity "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4888
                              _markStack._failed_double,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4889
                              _markStack.capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4890
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4891
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4892
  _markStack._hit_limit = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4893
  _markStack._failed_double = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4894
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4895
  if ((VerifyAfterGC || VerifyDuringGC) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4896
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4897
    verify_after_remark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4898
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4899
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4900
  // Change under the freelistLocks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4901
  _collectorState = Sweeping;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4902
  // Call isAllClear() under bitMapLock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4903
  assert(_modUnionTable.isAllClear(), "Should be clear by end of the"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4904
    " final marking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4905
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4906
    size_policy()->checkpoint_roots_final_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4907
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4908
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4909
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4910
// Parallel remark task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4911
class CMSParRemarkTask: public AbstractGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4912
  CMSCollector* _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4913
  WorkGang*     _workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4914
  int           _n_workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4915
  CompactibleFreeListSpace* _cms_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4916
  CompactibleFreeListSpace* _perm_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4917
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4918
  // The per-thread work queues, available here for stealing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4919
  OopTaskQueueSet*       _task_queues;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4920
  ParallelTaskTerminator _term;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4921
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4922
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4923
  CMSParRemarkTask(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4924
                   CompactibleFreeListSpace* cms_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4925
                   CompactibleFreeListSpace* perm_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4926
                   int n_workers, WorkGang* workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4927
                   OopTaskQueueSet* task_queues):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4928
    AbstractGangTask("Rescan roots and grey objects in parallel"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4929
    _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4930
    _cms_space(cms_space), _perm_space(perm_space),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4931
    _n_workers(n_workers),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4932
    _workers(workers),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4933
    _task_queues(task_queues),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4934
    _term(workers->total_workers(), task_queues) { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4935
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4936
  OopTaskQueueSet* task_queues() { return _task_queues; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4937
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4938
  OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4939
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4940
  ParallelTaskTerminator* terminator() { return &_term; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4941
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4942
  void work(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4943
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4944
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4945
  // Work method in support of parallel rescan ... of young gen spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4946
  void do_young_space_rescan(int i, Par_MarkRefsIntoAndScanClosure* cl,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4947
                             ContiguousSpace* space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4948
                             HeapWord** chunk_array, size_t chunk_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4949
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4950
  // ... of  dirty cards in old space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4951
  void do_dirty_card_rescan_tasks(CompactibleFreeListSpace* sp, int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4952
                                  Par_MarkRefsIntoAndScanClosure* cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4953
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4954
  // ... work stealing for the above
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4955
  void do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl, int* seed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4956
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4957
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4958
void CMSParRemarkTask::work(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4959
  elapsedTimer _timer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4960
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4961
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4962
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4963
  // ---------- rescan from roots --------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4964
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4965
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4966
  Par_MarkRefsIntoAndScanClosure par_mrias_cl(_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4967
    _collector->_span, _collector->ref_processor(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4968
    &(_collector->_markBitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4969
    work_queue(i), &(_collector->_revisitStack));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4970
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4971
  // Rescan young gen roots first since these are likely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4972
  // coarsely partitioned and may, on that account, constitute
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4973
  // the critical path; thus, it's best to start off that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4974
  // work first.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4975
  // ---------- young gen roots --------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4976
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4977
    DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4978
    EdenSpace* eden_space = dng->eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4979
    ContiguousSpace* from_space = dng->from();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4980
    ContiguousSpace* to_space   = dng->to();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4981
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4982
    HeapWord** eca = _collector->_eden_chunk_array;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4983
    size_t     ect = _collector->_eden_chunk_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4984
    HeapWord** sca = _collector->_survivor_chunk_array;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4985
    size_t     sct = _collector->_survivor_chunk_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4986
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4987
    assert(ect <= _collector->_eden_chunk_capacity, "out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4988
    assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4989
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4990
    do_young_space_rescan(i, &par_mrias_cl, to_space, NULL, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4991
    do_young_space_rescan(i, &par_mrias_cl, from_space, sca, sct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4992
    do_young_space_rescan(i, &par_mrias_cl, eden_space, eca, ect);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4993
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4994
    _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4995
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4996
      gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4997
        "Finished young gen rescan work in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4998
        i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4999
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5000
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5001
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5002
  // ---------- remaining roots --------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5003
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5004
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5005
  gch->gen_process_strong_roots(_collector->_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5006
                                false,     // yg was scanned above
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5007
                                true,      // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5008
                                SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5009
                                NULL, &par_mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5010
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5011
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5012
    gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5013
      "Finished remaining root rescan work in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5014
      i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5015
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5016
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5017
  // ---------- rescan dirty cards ------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5018
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5019
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5020
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5021
  // Do the rescan tasks for each of the two spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5022
  // (cms_space and perm_space) in turn.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5023
  do_dirty_card_rescan_tasks(_cms_space, i, &par_mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5024
  do_dirty_card_rescan_tasks(_perm_space, i, &par_mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5025
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5026
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5027
    gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5028
      "Finished dirty card rescan work in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5029
      i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5030
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5031
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5032
  // ---------- steal work from other threads ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5033
  // ---------- ... and drain overflow list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5034
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5035
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5036
  do_work_steal(i, &par_mrias_cl, _collector->hash_seed(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5037
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5038
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5039
    gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5040
      "Finished work stealing in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5041
      i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5042
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5043
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5044
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5045
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5046
CMSParRemarkTask::do_young_space_rescan(int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5047
  Par_MarkRefsIntoAndScanClosure* cl, ContiguousSpace* space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5048
  HeapWord** chunk_array, size_t chunk_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5049
  // Until all tasks completed:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5050
  // . claim an unclaimed task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5051
  // . compute region boundaries corresponding to task claimed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5052
  //   using chunk_array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5053
  // . par_oop_iterate(cl) over that region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5054
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5055
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5056
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5057
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5058
  SequentialSubTasksDone* pst = space->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5059
  assert(pst->valid(), "Uninitialized use?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5060
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5061
  int nth_task = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5062
  int n_tasks  = pst->n_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5063
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5064
  HeapWord *start, *end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5065
  while (!pst->is_task_claimed(/* reference */ nth_task)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5066
    // We claimed task # nth_task; compute its boundaries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5067
    if (chunk_top == 0) {  // no samples were taken
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5068
      assert(nth_task == 0 && n_tasks == 1, "Can have only 1 EdenSpace task");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5069
      start = space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5070
      end   = space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5071
    } else if (nth_task == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5072
      start = space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5073
      end   = chunk_array[nth_task];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5074
    } else if (nth_task < (jint)chunk_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5075
      assert(nth_task >= 1, "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5076
      start = chunk_array[nth_task - 1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5077
      end   = chunk_array[nth_task];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5078
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5079
      assert(nth_task == (jint)chunk_top, "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5080
      start = chunk_array[chunk_top - 1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5081
      end   = space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5082
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5083
    MemRegion mr(start, end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5084
    // Verify that mr is in space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5085
    assert(mr.is_empty() || space->used_region().contains(mr),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5086
           "Should be in space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5087
    // Verify that "start" is an object boundary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5088
    assert(mr.is_empty() || oop(mr.start())->is_oop(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5089
           "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5090
    space->par_oop_iterate(mr, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5091
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5092
  pst->all_tasks_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5093
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5094
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5095
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5096
CMSParRemarkTask::do_dirty_card_rescan_tasks(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5097
  CompactibleFreeListSpace* sp, int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5098
  Par_MarkRefsIntoAndScanClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5099
  // Until all tasks completed:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5100
  // . claim an unclaimed task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5101
  // . compute region boundaries corresponding to task claimed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5102
  // . transfer dirty bits ct->mut for that region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5103
  // . apply rescanclosure to dirty mut bits for that region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5105
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5106
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5107
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5108
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5109
  ModUnionClosure modUnionClosure(&(_collector->_modUnionTable));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5110
  // CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! CAUTION!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5111
  // CAUTION: This closure has state that persists across calls to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5112
  // the work method dirty_range_iterate_clear() in that it has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5113
  // imbedded in it a (subtype of) UpwardsObjectClosure. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5114
  // use of that state in the imbedded UpwardsObjectClosure instance
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5115
  // assumes that the cards are always iterated (even if in parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5116
  // by several threads) in monotonically increasing order per each
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5117
  // thread. This is true of the implementation below which picks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5118
  // card ranges (chunks) in monotonically increasing order globally
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5119
  // and, a-fortiori, in monotonically increasing order per thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5120
  // (the latter order being a subsequence of the former).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5121
  // If the work code below is ever reorganized into a more chaotic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5122
  // work-partitioning form than the current "sequential tasks"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5123
  // paradigm, the use of that persistent state will have to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5124
  // revisited and modified appropriately. See also related
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5125
  // bug 4756801 work on which should examine this code to make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5126
  // sure that the changes there do not run counter to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5127
  // assumptions made here and necessary for correctness and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5128
  // efficiency. Note also that this code might yield inefficient
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5129
  // behaviour in the case of very large objects that span one or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5130
  // more work chunks. Such objects would potentially be scanned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5131
  // several times redundantly. Work on 4756801 should try and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5132
  // address that performance anomaly if at all possible. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5133
  MemRegion  full_span  = _collector->_span;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5134
  CMSBitMap* bm    = &(_collector->_markBitMap);     // shared
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5135
  CMSMarkStack* rs = &(_collector->_revisitStack);   // shared
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5136
  MarkFromDirtyCardsClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5137
    greyRescanClosure(_collector, full_span, // entire span of interest
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5138
                      sp, bm, work_q, rs, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5139
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5140
  SequentialSubTasksDone* pst = sp->conc_par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5141
  assert(pst->valid(), "Uninitialized use?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5142
  int nth_task = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5143
  const int alignment = CardTableModRefBS::card_size * BitsPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5144
  MemRegion span = sp->used_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5145
  HeapWord* start_addr = span.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5146
  HeapWord* end_addr = (HeapWord*)round_to((intptr_t)span.end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5147
                                           alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5148
  const size_t chunk_size = sp->rescan_task_size(); // in HeapWord units
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5149
  assert((HeapWord*)round_to((intptr_t)start_addr, alignment) ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5150
         start_addr, "Check alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5151
  assert((size_t)round_to((intptr_t)chunk_size, alignment) ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5152
         chunk_size, "Check alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5153
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5154
  while (!pst->is_task_claimed(/* reference */ nth_task)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5155
    // Having claimed the nth_task, compute corresponding mem-region,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5156
    // which is a-fortiori aligned correctly (i.e. at a MUT bopundary).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5157
    // The alignment restriction ensures that we do not need any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5158
    // synchronization with other gang-workers while setting or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5159
    // clearing bits in thus chunk of the MUT.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5160
    MemRegion this_span = MemRegion(start_addr + nth_task*chunk_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5161
                                    start_addr + (nth_task+1)*chunk_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5162
    // The last chunk's end might be way beyond end of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5163
    // used region. In that case pull back appropriately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5164
    if (this_span.end() > end_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5165
      this_span.set_end(end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5166
      assert(!this_span.is_empty(), "Program logic (calculation of n_tasks)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5167
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5168
    // Iterate over the dirty cards covering this chunk, marking them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5169
    // precleaned, and setting the corresponding bits in the mod union
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5170
    // table. Since we have been careful to partition at Card and MUT-word
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5171
    // boundaries no synchronization is needed between parallel threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5172
    _collector->_ct->ct_bs()->dirty_card_iterate(this_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5173
                                                 &modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5174
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5175
    // Having transferred these marks into the modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5176
    // rescan the marked objects on the dirty cards in the modUnionTable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5177
    // Even if this is at a synchronous collection, the initial marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5178
    // may have been done during an asynchronous collection so there
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5179
    // may be dirty bits in the mod-union table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5180
    _collector->_modUnionTable.dirty_range_iterate_clear(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5181
                  this_span, &greyRescanClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5182
    _collector->_modUnionTable.verifyNoOneBitsInRange(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5183
                                 this_span.start(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5184
                                 this_span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5185
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5186
  pst->all_tasks_completed();  // declare that i am done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5187
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5188
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5189
// . see if we can share work_queues with ParNew? XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5190
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5191
CMSParRemarkTask::do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5192
                                int* seed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5193
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5194
  NOT_PRODUCT(int num_steals = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5195
  oop obj_to_scan;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5196
  CMSBitMap* bm = &(_collector->_markBitMap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5197
  size_t num_from_overflow_list =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5198
           MIN2((size_t)work_q->max_elems()/4,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5199
                (size_t)ParGCDesiredObjsFromOverflowList);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5200
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5201
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5202
    // Completely finish any left over work from (an) earlier round(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5203
    cl->trim_queue(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5204
    // Now check if there's any work in the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5205
    if (_collector->par_take_from_overflow_list(num_from_overflow_list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5206
                                                work_q)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5207
      // found something in global overflow list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5208
      // not yet ready to go stealing work from others.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5209
      // We'd like to assert(work_q->size() != 0, ...)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5210
      // because we just took work from the overflow list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5211
      // but of course we can't since all of that could have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5212
      // been already stolen from us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5213
      // "He giveth and He taketh away."
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5214
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5215
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5216
    // Verify that we have no work before we resort to stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5217
    assert(work_q->size() == 0, "Have work, shouldn't steal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5218
    // Try to steal from other queues that have work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5219
    if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5220
      NOT_PRODUCT(num_steals++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5221
      assert(obj_to_scan->is_oop(), "Oops, not an oop!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5222
      assert(bm->isMarked((HeapWord*)obj_to_scan), "Stole an unmarked oop?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5223
      // Do scanning work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5224
      obj_to_scan->oop_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5225
      // Loop around, finish this work, and try to steal some more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5226
    } else if (terminator()->offer_termination()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5227
        break;  // nirvana from the infinite cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5228
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5229
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5230
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5231
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5232
      gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5233
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5234
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5235
  assert(work_q->size() == 0 && _collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5236
         "Else our work is not yet done");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5237
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5238
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5239
// Return a thread-local PLAB recording array, as appropriate.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5240
void* CMSCollector::get_data_recorder(int thr_num) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5241
  if (_survivor_plab_array != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5242
      (CMSPLABRecordAlways ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5243
       (_collectorState > Marking && _collectorState < FinalMarking))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5244
    assert(thr_num < (int)ParallelGCThreads, "thr_num is out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5245
    ChunkArray* ca = &_survivor_plab_array[thr_num];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5246
    ca->reset();   // clear it so that fresh data is recorded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5247
    return (void*) ca;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5248
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5249
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5250
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5251
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5252
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5253
// Reset all the thread-local PLAB recording arrays
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5254
void CMSCollector::reset_survivor_plab_arrays() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5255
  for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5256
    _survivor_plab_array[i].reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5257
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5258
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5259
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5260
// Merge the per-thread plab arrays into the global survivor chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5261
// array which will provide the partitioning of the survivor space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5262
// for CMS rescan.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5263
void CMSCollector::merge_survivor_plab_arrays(ContiguousSpace* surv) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5264
  assert(_survivor_plab_array  != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5265
  assert(_survivor_chunk_array != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5266
  assert(_collectorState == FinalMarking, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5267
  for (uint j = 0; j < ParallelGCThreads; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5268
    _cursor[j] = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5269
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5270
  HeapWord* top = surv->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5271
  size_t i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5272
  for (i = 0; i < _survivor_chunk_capacity; i++) {  // all sca entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5273
    HeapWord* min_val = top;          // Higher than any PLAB address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5274
    uint      min_tid = 0;            // position of min_val this round
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5275
    for (uint j = 0; j < ParallelGCThreads; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5276
      ChunkArray* cur_sca = &_survivor_plab_array[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5277
      if (_cursor[j] == cur_sca->end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5278
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5279
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5280
      assert(_cursor[j] < cur_sca->end(), "ctl pt invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5281
      HeapWord* cur_val = cur_sca->nth(_cursor[j]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5282
      assert(surv->used_region().contains(cur_val), "Out of bounds value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5283
      if (cur_val < min_val) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5284
        min_tid = j;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5285
        min_val = cur_val;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5286
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5287
        assert(cur_val < top, "All recorded addresses should be less");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5288
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5289
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5290
    // At this point min_val and min_tid are respectively
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5291
    // the least address in _survivor_plab_array[j]->nth(_cursor[j])
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5292
    // and the thread (j) that witnesses that address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5293
    // We record this address in the _survivor_chunk_array[i]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5294
    // and increment _cursor[min_tid] prior to the next round i.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5295
    if (min_val == top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5296
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5297
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5298
    _survivor_chunk_array[i] = min_val;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5299
    _cursor[min_tid]++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5300
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5301
  // We are all done; record the size of the _survivor_chunk_array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5302
  _survivor_chunk_index = i; // exclusive: [0, i)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5303
  if (PrintCMSStatistics > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5304
    gclog_or_tty->print(" (Survivor:" SIZE_FORMAT "chunks) ", i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5305
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5306
  // Verify that we used up all the recorded entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5307
  #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5308
    size_t total = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5309
    for (uint j = 0; j < ParallelGCThreads; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5310
      assert(_cursor[j] == _survivor_plab_array[j].end(), "Ctl pt invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5311
      total += _cursor[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5312
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5313
    assert(total == _survivor_chunk_index, "Ctl Pt Invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5314
    // Check that the merged array is in sorted order
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5315
    if (total > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5316
      for (size_t i = 0; i < total - 1; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5317
        if (PrintCMSStatistics > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5318
          gclog_or_tty->print(" (chunk" SIZE_FORMAT ":" INTPTR_FORMAT ") ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5319
                              i, _survivor_chunk_array[i]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5320
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5321
        assert(_survivor_chunk_array[i] < _survivor_chunk_array[i+1],
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5322
               "Not sorted");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5323
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5324
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5325
  #endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5326
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5327
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5328
// Set up the space's par_seq_tasks structure for work claiming
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5329
// for parallel rescan of young gen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5330
// See ParRescanTask where this is currently used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5331
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5332
CMSCollector::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5333
initialize_sequential_subtasks_for_young_gen_rescan(int n_threads) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5334
  assert(n_threads > 0, "Unexpected n_threads argument");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5335
  DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5336
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5337
  // Eden space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5338
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5339
    SequentialSubTasksDone* pst = dng->eden()->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5340
    assert(!pst->valid(), "Clobbering existing data?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5341
    // Each valid entry in [0, _eden_chunk_index) represents a task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5342
    size_t n_tasks = _eden_chunk_index + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5343
    assert(n_tasks == 1 || _eden_chunk_array != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5344
    pst->set_par_threads(n_threads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5345
    pst->set_n_tasks((int)n_tasks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5346
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5347
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5348
  // Merge the survivor plab arrays into _survivor_chunk_array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5349
  if (_survivor_plab_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5350
    merge_survivor_plab_arrays(dng->from());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5351
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5352
    assert(_survivor_chunk_index == 0, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5353
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5354
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5355
  // To space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5356
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5357
    SequentialSubTasksDone* pst = dng->to()->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5358
    assert(!pst->valid(), "Clobbering existing data?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5359
    pst->set_par_threads(n_threads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5360
    pst->set_n_tasks(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5361
    assert(pst->valid(), "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5362
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5363
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5364
  // From space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5365
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5366
    SequentialSubTasksDone* pst = dng->from()->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5367
    assert(!pst->valid(), "Clobbering existing data?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5368
    size_t n_tasks = _survivor_chunk_index + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5369
    assert(n_tasks == 1 || _survivor_chunk_array != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5370
    pst->set_par_threads(n_threads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5371
    pst->set_n_tasks((int)n_tasks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5372
    assert(pst->valid(), "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5373
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5374
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5375
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5376
// Parallel version of remark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5377
void CMSCollector::do_remark_parallel() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5378
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5379
  WorkGang* workers = gch->workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5380
  assert(workers != NULL, "Need parallel worker threads.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5381
  int n_workers = workers->total_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5382
  CompactibleFreeListSpace* cms_space  = _cmsGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5383
  CompactibleFreeListSpace* perm_space = _permGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5384
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5385
  CMSParRemarkTask tsk(this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5386
    cms_space, perm_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5387
    n_workers, workers, task_queues());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5388
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5389
  // Set up for parallel process_strong_roots work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5390
  gch->set_par_threads(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5391
  gch->change_strong_roots_parity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5392
  // We won't be iterating over the cards in the card table updating
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5393
  // the younger_gen cards, so we shouldn't call the following else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5394
  // the verification code as well as subsequent younger_refs_iterate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5395
  // code would get confused. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5396
  // gch->rem_set()->prepare_for_younger_refs_iterate(true); // parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5397
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5398
  // The young gen rescan work will not be done as part of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5399
  // process_strong_roots (which currently doesn't knw how to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5400
  // parallelize such a scan), but rather will be broken up into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5401
  // a set of parallel tasks (via the sampling that the [abortable]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5402
  // preclean phase did of EdenSpace, plus the [two] tasks of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5403
  // scanning the [two] survivor spaces. Further fine-grain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5404
  // parallelization of the scanning of the survivor spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5405
  // themselves, and of precleaning of the younger gen itself
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5406
  // is deferred to the future.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5407
  initialize_sequential_subtasks_for_young_gen_rescan(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5408
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5409
  // The dirty card rescan work is broken up into a "sequence"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5410
  // of parallel tasks (per constituent space) that are dynamically
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5411
  // claimed by the parallel threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5412
  cms_space->initialize_sequential_subtasks_for_rescan(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5413
  perm_space->initialize_sequential_subtasks_for_rescan(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5414
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5415
  // It turns out that even when we're using 1 thread, doing the work in a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5416
  // separate thread causes wide variance in run times.  We can't help this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5417
  // in the multi-threaded case, but we special-case n=1 here to get
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5418
  // repeatable measurements of the 1-thread overhead of the parallel code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5419
  if (n_workers > 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5420
    // Make refs discovery MT-safe
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5421
    ReferenceProcessorMTMutator mt(ref_processor(), true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5422
    workers->run_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5423
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5424
    tsk.work(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5425
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5426
  gch->set_par_threads(0);  // 0 ==> non-parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5427
  // restore, single-threaded for now, any preserved marks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5428
  // as a result of work_q overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5429
  restore_preserved_marks_if_any();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5430
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5431
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5432
// Non-parallel version of remark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5433
void CMSCollector::do_remark_non_parallel() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5434
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5435
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5436
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5437
  MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5438
    mrias_cl(_span, ref_processor(), &_markBitMap, &_modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5439
             &_markStack, &_revisitStack, this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5440
             false /* should_yield */, false /* not precleaning */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5441
  MarkFromDirtyCardsClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5442
    markFromDirtyCardsClosure(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5443
                              NULL,  // space is set further below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5444
                              &_markBitMap, &_markStack, &_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5445
                              &mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5446
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5447
    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
  5448
    // 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
  5449
    // mod union table.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5450
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5451
      ModUnionClosure modUnionClosure(&_modUnionTable);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5452
      _ct->ct_bs()->dirty_card_iterate(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5453
                      _cmsGen->used_region(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5454
                      &modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5455
      _ct->ct_bs()->dirty_card_iterate(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5456
                      _permGen->used_region(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5457
                      &modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5458
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5459
    // Having transferred these marks into the modUnionTable, we just need
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5460
    // to rescan the marked objects on the dirty cards in the modUnionTable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5461
    // The initial marking may have been done during an asynchronous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5462
    // collection so there may be dirty bits in the mod-union table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5463
    const int alignment =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5464
      CardTableModRefBS::card_size * BitsPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5465
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5466
      // ... First handle dirty cards in CMS gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5467
      markFromDirtyCardsClosure.set_space(_cmsGen->cmsSpace());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5468
      MemRegion ur = _cmsGen->used_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5469
      HeapWord* lb = ur.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5470
      HeapWord* ub = (HeapWord*)round_to((intptr_t)ur.end(), alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5471
      MemRegion cms_span(lb, ub);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5472
      _modUnionTable.dirty_range_iterate_clear(cms_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5473
                                               &markFromDirtyCardsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5474
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5475
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5476
        gclog_or_tty->print(" (re-scanned "SIZE_FORMAT" dirty cards in cms gen) ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5477
          markFromDirtyCardsClosure.num_dirty_cards());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5478
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5479
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5480
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5481
      // .. and then repeat for dirty cards in perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5482
      markFromDirtyCardsClosure.set_space(_permGen->cmsSpace());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5483
      MemRegion ur = _permGen->used_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5484
      HeapWord* lb = ur.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5485
      HeapWord* ub = (HeapWord*)round_to((intptr_t)ur.end(), alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5486
      MemRegion perm_span(lb, ub);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5487
      _modUnionTable.dirty_range_iterate_clear(perm_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5488
                                               &markFromDirtyCardsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5489
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5490
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5491
        gclog_or_tty->print(" (re-scanned "SIZE_FORMAT" dirty cards in perm gen) ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5492
          markFromDirtyCardsClosure.num_dirty_cards());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5493
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5494
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5495
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5496
  if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5497
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5498
    HandleMark hm;  // Discard invalid handles created during verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5499
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5500
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5501
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5502
    TraceTime t("root rescan", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5503
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5504
    verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5505
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5506
    gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5507
    gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5508
                                  true,  // younger gens as roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5509
                                  true,  // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5510
                                  SharedHeap::ScanningOption(roots_scanning_options()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5511
                                  NULL, &mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5512
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5513
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5514
  // Restore evacuated mark words, if any, used for overflow list links
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5515
  if (!CMSOverflowEarlyRestoration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5516
    restore_preserved_marks_if_any();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5517
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5518
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5519
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5520
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5521
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5522
// Parallel Reference Processing Task Proxy Class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5523
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5524
class CMSRefProcTaskProxy: public AbstractGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5525
  typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5526
  CMSCollector*          _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5527
  CMSBitMap*             _mark_bit_map;
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5528
  const MemRegion        _span;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5529
  OopTaskQueueSet*       _task_queues;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5530
  ParallelTaskTerminator _term;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5531
  ProcessTask&           _task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5532
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5533
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5534
  CMSRefProcTaskProxy(ProcessTask&     task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5535
                      CMSCollector*    collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5536
                      const MemRegion& span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5537
                      CMSBitMap*       mark_bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5538
                      int              total_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5539
                      OopTaskQueueSet* task_queues):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5540
    AbstractGangTask("Process referents by policy in parallel"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5541
    _task(task),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5542
    _collector(collector), _span(span), _mark_bit_map(mark_bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5543
    _task_queues(task_queues),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5544
    _term(total_workers, task_queues)
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5545
    {
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5546
      assert(_collector->_span.equals(_span) && !_span.is_empty(),
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5547
             "Inconsistency in _span");
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5548
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5549
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5550
  OopTaskQueueSet* task_queues() { return _task_queues; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5551
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5552
  OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5553
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5554
  ParallelTaskTerminator* terminator() { return &_term; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5555
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5556
  void do_work_steal(int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5557
                     CMSParDrainMarkingStackClosure* drain,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5558
                     CMSParKeepAliveClosure* keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5559
                     int* seed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5560
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5561
  virtual void work(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5562
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5563
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5564
void CMSRefProcTaskProxy::work(int i) {
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5565
  assert(_collector->_span.equals(_span), "Inconsistency in _span");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5566
  CMSParKeepAliveClosure par_keep_alive(_collector, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5567
                                        _mark_bit_map, work_queue(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5568
  CMSParDrainMarkingStackClosure par_drain_stack(_collector, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5569
                                                 _mark_bit_map, work_queue(i));
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5570
  CMSIsAliveClosure is_alive_closure(_span, _mark_bit_map);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5571
  _task.work(i, is_alive_closure, par_keep_alive, par_drain_stack);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5572
  if (_task.marks_oops_alive()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5573
    do_work_steal(i, &par_drain_stack, &par_keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5574
                  _collector->hash_seed(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5575
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5576
  assert(work_queue(i)->size() == 0, "work_queue should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5577
  assert(_collector->_overflow_list == NULL, "non-empty _overflow_list");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5578
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5579
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5580
class CMSRefEnqueueTaskProxy: public AbstractGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5581
  typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5582
  EnqueueTask& _task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5583
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5584
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5585
  CMSRefEnqueueTaskProxy(EnqueueTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5586
    : AbstractGangTask("Enqueue reference objects in parallel"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5587
      _task(task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5588
  { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5589
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5590
  virtual void work(int i)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5591
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5592
    _task.work(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5593
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5594
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5595
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5596
CMSParKeepAliveClosure::CMSParKeepAliveClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5597
  MemRegion span, CMSBitMap* bit_map, OopTaskQueue* work_queue):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5598
   _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5599
   _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5600
   _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5601
   _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5602
   _mark_and_push(collector, span, bit_map, work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5603
   _low_water_mark(MIN2((uint)(work_queue->max_elems()/4),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5604
                        (uint)(CMSWorkQueueDrainThreshold * ParallelGCThreads)))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5605
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5606
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5607
// . see if we can share work_queues with ParNew? XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5608
void CMSRefProcTaskProxy::do_work_steal(int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5609
  CMSParDrainMarkingStackClosure* drain,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5610
  CMSParKeepAliveClosure* keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5611
  int* seed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5612
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5613
  NOT_PRODUCT(int num_steals = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5614
  oop obj_to_scan;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5615
  size_t num_from_overflow_list =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5616
           MIN2((size_t)work_q->max_elems()/4,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5617
                (size_t)ParGCDesiredObjsFromOverflowList);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5618
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5619
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5620
    // Completely finish any left over work from (an) earlier round(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5621
    drain->trim_queue(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5622
    // Now check if there's any work in the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5623
    if (_collector->par_take_from_overflow_list(num_from_overflow_list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5624
                                                work_q)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5625
      // Found something in global overflow list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5626
      // not yet ready to go stealing work from others.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5627
      // We'd like to assert(work_q->size() != 0, ...)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5628
      // because we just took work from the overflow list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5629
      // but of course we can't, since all of that might have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5630
      // been already stolen from us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5631
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5632
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5633
    // Verify that we have no work before we resort to stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5634
    assert(work_q->size() == 0, "Have work, shouldn't steal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5635
    // Try to steal from other queues that have work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5636
    if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5637
      NOT_PRODUCT(num_steals++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5638
      assert(obj_to_scan->is_oop(), "Oops, not an oop!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5639
      assert(_mark_bit_map->isMarked((HeapWord*)obj_to_scan), "Stole an unmarked oop?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5640
      // Do scanning work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5641
      obj_to_scan->oop_iterate(keep_alive);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5642
      // Loop around, finish this work, and try to steal some more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5643
    } else if (terminator()->offer_termination()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5644
      break;  // nirvana from the infinite cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5645
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5646
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5647
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5648
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5649
      gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5650
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5651
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5652
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5653
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5654
void CMSRefProcTaskExecutor::execute(ProcessTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5655
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5656
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5657
  WorkGang* workers = gch->workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5658
  assert(workers != NULL, "Need parallel worker threads.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5659
  int n_workers = workers->total_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5660
  CMSRefProcTaskProxy rp_task(task, &_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5661
                              _collector.ref_processor()->span(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5662
                              _collector.markBitMap(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5663
                              n_workers, _collector.task_queues());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5664
  workers->run_task(&rp_task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5665
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5666
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5667
void CMSRefProcTaskExecutor::execute(EnqueueTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5668
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5669
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5670
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5671
  WorkGang* workers = gch->workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5672
  assert(workers != NULL, "Need parallel worker threads.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5673
  CMSRefEnqueueTaskProxy enq_task(task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5674
  workers->run_task(&enq_task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5675
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5676
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5677
void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5678
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5679
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5680
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5681
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5682
  ReferenceProcessor* rp = ref_processor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5683
  assert(rp->span().equals(_span), "Spans should be equal");
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5684
  assert(!rp->enqueuing_is_done(), "Enqueuing should not be complete");
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5685
  // Process weak references.
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5686
  rp->snap_policy(clear_all_soft_refs);
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5687
  verify_work_stacks_empty();
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5688
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5689
  CMSKeepAliveClosure cmsKeepAliveClosure(this, _span, &_markBitMap,
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  5690
                                          &_markStack, false /* !preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5691
  CMSDrainMarkingStackClosure cmsDrainMarkingStackClosure(this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5692
                                _span, &_markBitMap, &_markStack,
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  5693
                                &cmsKeepAliveClosure, false /* !preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5694
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5695
    TraceTime t("weak refs processing", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5696
    if (rp->processing_is_mt()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5697
      CMSRefProcTaskExecutor task_executor(*this);
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5698
      rp->process_discovered_references(&_is_alive_closure,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5699
                                        &cmsKeepAliveClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5700
                                        &cmsDrainMarkingStackClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5701
                                        &task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5702
    } else {
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5703
      rp->process_discovered_references(&_is_alive_closure,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5704
                                        &cmsKeepAliveClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5705
                                        &cmsDrainMarkingStackClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5706
                                        NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5707
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5708
    verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5709
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5710
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  5711
  if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5712
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5713
      TraceTime t("class unloading", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5714
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5715
      // Follow SystemDictionary roots and unload classes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5716
      bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5717
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5718
      // Follow CodeCache roots and unload any methods marked for unloading
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5719
      CodeCache::do_unloading(&_is_alive_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5720
                              &cmsKeepAliveClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5721
                              purged_class);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5722
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5723
      cmsDrainMarkingStackClosure.do_void();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5724
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5725
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5726
      // Update subklass/sibling/implementor links in KlassKlass descendants
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5727
      assert(!_revisitStack.isEmpty(), "revisit stack should not be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5728
      oop k;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5729
      while ((k = _revisitStack.pop()) != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5730
        ((Klass*)(oopDesc*)k)->follow_weak_klass_links(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5731
                       &_is_alive_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5732
                       &cmsKeepAliveClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5733
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5734
      assert(!ClassUnloading ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5735
             (_markStack.isEmpty() && overflow_list_is_empty()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5736
             "Should not have found new reachable objects");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5737
      assert(_revisitStack.isEmpty(), "revisit stack should have been drained");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5738
      cmsDrainMarkingStackClosure.do_void();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5739
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5740
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5741
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5742
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5743
      TraceTime t("scrub symbol & string tables", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5744
      // Now clean up stale oops in SymbolTable and StringTable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5745
      SymbolTable::unlink(&_is_alive_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5746
      StringTable::unlink(&_is_alive_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5747
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5748
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5749
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5750
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5751
  // Restore any preserved marks as a result of mark stack or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5752
  // work queue overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5753
  restore_preserved_marks_if_any();  // done single-threaded for now
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5754
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5755
  rp->set_enqueuing_is_done(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5756
  if (rp->processing_is_mt()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5757
    CMSRefProcTaskExecutor task_executor(*this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5758
    rp->enqueue_discovered_references(&task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5759
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5760
    rp->enqueue_discovered_references(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5761
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5762
  rp->verify_no_references_recorded();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5763
  assert(!rp->discovery_enabled(), "should have been disabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5764
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5765
  // JVMTI object tagging is based on JNI weak refs. If any of these
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5766
  // refs were cleared then JVMTI needs to update its maps and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5767
  // maybe post ObjectFrees to agents.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5768
  JvmtiExport::cms_ref_processing_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5769
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5770
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5771
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5772
void CMSCollector::check_correct_thread_executing() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5773
  Thread* t = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5774
  // Only the VM thread or the CMS thread should be here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5775
  assert(t->is_ConcurrentGC_thread() || t->is_VM_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5776
         "Unexpected thread type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5777
  // If this is the vm thread, the foreground process
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5778
  // should not be waiting.  Note that _foregroundGCIsActive is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5779
  // true while the foreground collector is waiting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5780
  if (_foregroundGCShouldWait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5781
    // We cannot be the VM thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5782
    assert(t->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5783
           "Should be CMS thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5784
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5785
    // We can be the CMS thread only if we are in a stop-world
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5786
    // phase of CMS collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5787
    if (t->is_ConcurrentGC_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5788
      assert(_collectorState == InitialMarking ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5789
             _collectorState == FinalMarking,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5790
             "Should be a stop-world phase");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5791
      // The CMS thread should be holding the CMS_token.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5792
      assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5793
             "Potential interference with concurrently "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5794
             "executing VM thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5795
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5796
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5797
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5798
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5799
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5800
void CMSCollector::sweep(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5801
  assert(_collectorState == Sweeping, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5802
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5803
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5804
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5805
  incrementSweepCount();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5806
  _sweep_timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5807
  _sweep_estimate.sample(_sweep_timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5808
  size_policy()->avg_cms_free_at_sweep()->sample(_cmsGen->free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5809
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5810
  // PermGen verification support: If perm gen sweeping is disabled in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5811
  // this cycle, we preserve the perm gen object "deadness" information
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5812
  // in the perm_gen_verify_bit_map. In order to do that we traverse
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5813
  // 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
  5814
  if (verifying() && !should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5815
    assert(perm_gen_verify_bit_map()->sizeInBits() != 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5816
           "Should have already been allocated");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5817
    MarkDeadObjectsClosure mdo(this, _permGen->cmsSpace(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5818
                               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
  5819
    if (asynch) {
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5820
      CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(),
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5821
                               bitMapLock());
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5822
      _permGen->cmsSpace()->blk_iterate(&mdo);
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5823
    } else {
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5824
      // 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
  5825
      // the requisite locks/tokens.
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5826
      _permGen->cmsSpace()->blk_iterate(&mdo);
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5827
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5828
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5829
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5830
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5831
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5832
    CMSPhaseAccounting pa(this, "sweep", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5833
    // First sweep the old gen then the perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5834
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5835
      CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5836
                               bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5837
      sweepWork(_cmsGen, asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5838
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5839
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5840
    // Now repeat for perm gen
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  5841
    if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5842
      CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5843
                             bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5844
      sweepWork(_permGen, asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5845
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5846
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5847
    // Update Universe::_heap_*_at_gc figures.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5848
    // We need all the free list locks to make the abstract state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5849
    // transition from Sweeping to Resetting. See detailed note
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5850
    // further below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5851
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5852
      CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5853
                               _permGen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5854
      // Update heap occupancy information which is used as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5855
      // input to soft ref clearing policy at the next gc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5856
      Universe::update_heap_info_at_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5857
      _collectorState = Resizing;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5858
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5859
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5860
    // already have needed locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5861
    sweepWork(_cmsGen,  asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5862
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  5863
    if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5864
      sweepWork(_permGen, asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5865
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5866
    // Update heap occupancy information which is used as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5867
    // input to soft ref clearing policy at the next gc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5868
    Universe::update_heap_info_at_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5869
    _collectorState = Resizing;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5870
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5871
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5872
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5873
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5874
  _sweep_timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5875
  _sweep_timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5876
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5877
  update_time_of_last_gc(os::javaTimeMillis());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5878
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5879
  // NOTE on abstract state transitions:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5880
  // Mutators allocate-live and/or mark the mod-union table dirty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5881
  // based on the state of the collection.  The former is done in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5882
  // the interval [Marking, Sweeping] and the latter in the interval
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5883
  // [Marking, Sweeping).  Thus the transitions into the Marking state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5884
  // and out of the Sweeping state must be synchronously visible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5885
  // globally to the mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5886
  // The transition into the Marking state happens with the world
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5887
  // stopped so the mutators will globally see it.  Sweeping is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5888
  // done asynchronously by the background collector so the transition
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5889
  // from the Sweeping state to the Resizing state must be done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5890
  // under the freelistLock (as is the check for whether to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5891
  // allocate-live and whether to dirty the mod-union table).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5892
  assert(_collectorState == Resizing, "Change of collector state to"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5893
    " Resizing must be done under the freelistLocks (plural)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5894
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5895
  // Now that sweeping has been completed, if the GCH's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5896
  // incremental_collection_will_fail flag is set, clear it,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5897
  // thus inviting a younger gen collection to promote into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5898
  // this generation. If such a promotion may still fail,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5899
  // the flag will be set again when a young collection is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5900
  // attempted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5901
  // I think the incremental_collection_will_fail flag's use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5902
  // is specific to a 2 generation collection policy, so i'll
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5903
  // assert that that's the configuration we are operating within.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5904
  // The use of the flag can and should be generalized appropriately
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5905
  // in the future to deal with a general n-generation system.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5906
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5907
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5908
  assert(gch->collector_policy()->is_two_generation_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5909
         "Resetting of incremental_collection_will_fail flag"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5910
         " may be incorrect otherwise");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5911
  gch->clear_incremental_collection_will_fail();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5912
  gch->update_full_collections_completed(_collection_count_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5913
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5914
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5915
// FIX ME!!! Looks like this belongs in CFLSpace, with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5916
// CMSGen merely delegating to it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5917
void ConcurrentMarkSweepGeneration::setNearLargestChunk() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5918
  double nearLargestPercent = 0.999;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5919
  HeapWord*  minAddr        = _cmsSpace->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5920
  HeapWord*  largestAddr    =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5921
    (HeapWord*) _cmsSpace->dictionary()->findLargestDict();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5922
  if (largestAddr == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5923
    // The dictionary appears to be empty.  In this case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5924
    // try to coalesce at the end of the heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5925
    largestAddr = _cmsSpace->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5926
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5927
  size_t largestOffset     = pointer_delta(largestAddr, minAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5928
  size_t nearLargestOffset =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5929
    (size_t)((double)largestOffset * nearLargestPercent) - MinChunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5930
  _cmsSpace->set_nearLargestChunk(minAddr + nearLargestOffset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5931
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5932
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5933
bool ConcurrentMarkSweepGeneration::isNearLargestChunk(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5934
  return addr >= _cmsSpace->nearLargestChunk();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5935
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5936
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5937
FreeChunk* ConcurrentMarkSweepGeneration::find_chunk_at_end() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5938
  return _cmsSpace->find_chunk_at_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5939
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5940
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5941
void ConcurrentMarkSweepGeneration::update_gc_stats(int current_level,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5942
                                                    bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5943
  // The next lower level has been collected.  Gather any statistics
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5944
  // that are of interest at this point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5945
  if (!full && (current_level + 1) == level()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5946
    // Gather statistics on the young generation collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5947
    collector()->stats().record_gc0_end(used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5948
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5949
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5950
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5951
CMSAdaptiveSizePolicy* ConcurrentMarkSweepGeneration::size_policy() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5952
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5953
  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5954
    "Wrong type of heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5955
  CMSAdaptiveSizePolicy* sp = (CMSAdaptiveSizePolicy*)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5956
    gch->gen_policy()->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5957
  assert(sp->is_gc_cms_adaptive_size_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5958
    "Wrong type of size policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5959
  return sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5960
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5961
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5962
void ConcurrentMarkSweepGeneration::rotate_debug_collection_type() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5963
  if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5964
    gclog_or_tty->print("Rotate from %d ", _debug_collection_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5965
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5966
  _debug_collection_type = (CollectionTypes) (_debug_collection_type + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5967
  _debug_collection_type =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5968
    (CollectionTypes) (_debug_collection_type % Unknown_collection_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5969
  if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5970
    gclog_or_tty->print_cr("to %d ", _debug_collection_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5971
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5972
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5973
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5974
void CMSCollector::sweepWork(ConcurrentMarkSweepGeneration* gen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5975
  bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5976
  // We iterate over the space(s) underlying this generation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5977
  // checking the mark bit map to see if the bits corresponding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5978
  // to specific blocks are marked or not. Blocks that are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5979
  // marked are live and are not swept up. All remaining blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5980
  // are swept up, with coalescing on-the-fly as we sweep up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5981
  // contiguous free and/or garbage blocks:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5982
  // We need to ensure that the sweeper synchronizes with allocators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5983
  // and stop-the-world collectors. In particular, the following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5984
  // locks are used:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5985
  // . CMS token: if this is held, a stop the world collection cannot occur
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5986
  // . freelistLock: if this is held no allocation can occur from this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5987
  //                 generation by another thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5988
  // . bitMapLock: if this is held, no other thread can access or update
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5989
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5990
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5991
  // Note that we need to hold the freelistLock if we use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5992
  // block iterate below; else the iterator might go awry if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5993
  // a mutator (or promotion) causes block contents to change
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5994
  // (for instance if the allocator divvies up a block).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5995
  // If we hold the free list lock, for all practical purposes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5996
  // young generation GC's can't occur (they'll usually need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5997
  // promote), so we might as well prevent all young generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5998
  // GC's while we do a sweeping step. For the same reason, we might
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5999
  // as well take the bit map lock for the entire duration
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6001
  // check that we hold the requisite locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6002
  assert(have_cms_token(), "Should hold cms token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6003
  assert(   (asynch && ConcurrentMarkSweepThread::cms_thread_has_cms_token())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6004
         || (!asynch && ConcurrentMarkSweepThread::vm_thread_has_cms_token()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6005
        "Should possess CMS token to sweep");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6006
  assert_lock_strong(gen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6007
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6009
  assert(!_sweep_timer.is_active(), "Was switched off in an outer context");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6010
  gen->cmsSpace()->beginSweepFLCensus((float)(_sweep_timer.seconds()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6011
                                      _sweep_estimate.padded_average());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6012
  gen->setNearLargestChunk();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6013
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6014
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6015
    SweepClosure sweepClosure(this, gen, &_markBitMap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6016
                            CMSYield && asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6017
    gen->cmsSpace()->blk_iterate_careful(&sweepClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6018
    // We need to free-up/coalesce garbage/blocks from a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6019
    // co-terminal free run. This is done in the SweepClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6020
    // destructor; so, do not remove this scope, else the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6021
    // end-of-sweep-census below will be off by a little bit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6022
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6023
  gen->cmsSpace()->sweep_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6024
  gen->cmsSpace()->endSweepFLCensus(sweepCount());
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6025
  if (should_unload_classes()) {                // unloaded classes this cycle,
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6026
    _concurrent_cycles_since_last_unload = 0;   // ... reset count
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6027
  } else {                                      // did not unload classes,
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6028
    _concurrent_cycles_since_last_unload++;     // ... increment count
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6029
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6030
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6031
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6032
// Reset CMS data structures (for now just the marking bit map)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6033
// preparatory for the next cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6034
void CMSCollector::reset(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6035
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6036
  CMSAdaptiveSizePolicy* sp = size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6037
  AdaptiveSizePolicyOutput(sp, gch->total_collections());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6038
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6039
    CMSTokenSyncWithLocks ts(true, bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6040
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6041
    // If the state is not "Resetting", the foreground  thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6042
    // has done a collection and the resetting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6043
    if (_collectorState != Resetting) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6044
      assert(_collectorState == Idling, "The state should only change"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6045
        " because the foreground collector has finished the collection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6046
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6047
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6048
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6049
    // Clear the mark bitmap (no grey objects to start with)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6050
    // for the next cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6051
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6052
    CMSPhaseAccounting cmspa(this, "reset", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6054
    HeapWord* curAddr = _markBitMap.startWord();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6055
    while (curAddr < _markBitMap.endWord()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6056
      size_t remaining  = pointer_delta(_markBitMap.endWord(), curAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6057
      MemRegion chunk(curAddr, MIN2(CMSBitMapYieldQuantum, remaining));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6058
      _markBitMap.clear_large_range(chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6059
      if (ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6060
          !foregroundGCIsActive() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6061
          CMSYield) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6062
        assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6063
               "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6064
        assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6065
        bitMapLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6066
        ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6067
        ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6068
        stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6069
        if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6070
          incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6071
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6072
        icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6073
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6074
        // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6075
        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
  6076
                         ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6077
                         !CMSCollector::foregroundGCIsActive(); ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6078
          os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6079
          ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6080
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6081
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6082
        ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6083
        bitMapLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6084
        startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6085
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6086
      curAddr = chunk.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6087
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6088
    _collectorState = Idling;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6089
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6090
    // already have the lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6091
    assert(_collectorState == Resetting, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6092
    assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6093
    _markBitMap.clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6094
    _collectorState = Idling;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6095
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6097
  // Stop incremental mode after a cycle completes, so that any future cycles
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6098
  // are triggered by allocation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6099
  stop_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6100
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6101
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6102
    if (RotateCMSCollectionTypes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6103
      _cmsGen->rotate_debug_collection_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6104
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6105
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6106
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6107
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6108
void CMSCollector::do_CMS_operation(CMS_op_type op) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6109
  gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6110
  TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6111
  TraceTime t("GC", PrintGC, !PrintGCDetails, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6112
  TraceCollectorStats tcs(counters());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6113
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6114
  switch (op) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6115
    case CMS_op_checkpointRootsInitial: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6116
      checkpointRootsInitial(true);       // asynch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6117
      if (PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6118
        _cmsGen->printOccupancy("initial-mark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6119
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6120
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6121
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6122
    case CMS_op_checkpointRootsFinal: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6123
      checkpointRootsFinal(true,    // asynch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6124
                           false,   // !clear_all_soft_refs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6125
                           false);  // !init_mark_was_synchronous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6126
      if (PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6127
        _cmsGen->printOccupancy("remark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6128
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6129
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6130
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6131
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6132
      fatal("No such CMS_op");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6133
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6134
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6135
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6136
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6137
size_t const CMSCollector::skip_header_HeapWords() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6138
  return FreeChunk::header_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6139
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6140
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6141
// Try and collect here conditions that should hold when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6142
// CMS thread is exiting. The idea is that the foreground GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6143
// thread should not be blocked if it wants to terminate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6144
// the CMS thread and yet continue to run the VM for a while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6145
// after that.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6146
void CMSCollector::verify_ok_to_terminate() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6147
  assert(Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6148
         "should be called by CMS thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6149
  assert(!_foregroundGCShouldWait, "should be false");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6150
  // We could check here that all the various low-level locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6151
  // are not held by the CMS thread, but that is overkill; see
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6152
  // also CMSThread::verify_ok_to_terminate() where the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6153
  // is checked.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6154
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6155
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6156
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6157
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
  6158
   assert(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1),
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  6159
          "missing Printezis mark?");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6160
  HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6161
  size_t size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6162
  assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6163
         "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6164
  assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6165
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6166
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6167
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6168
// A variant of the above (block_size_using_printezis_bits()) except
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6169
// that we return 0 if the P-bits are not yet set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6170
size_t CMSCollector::block_size_if_printezis_bits(HeapWord* addr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6171
  if (_markBitMap.isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6172
    assert(_markBitMap.isMarked(addr + 1), "Missing Printezis bit?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6173
    HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6174
    size_t size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6175
    assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6176
           "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6177
    assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6178
    return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6179
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6180
    assert(!_markBitMap.isMarked(addr + 1), "Bit map inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6181
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6182
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6183
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6184
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6185
HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6186
  size_t sz = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6187
  oop p = (oop)addr;
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6188
  if (p->klass_or_null() != NULL && p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6189
    sz = CompactibleFreeListSpace::adjustObjectSize(p->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6190
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6191
    sz = block_size_using_printezis_bits(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6192
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6193
  assert(sz > 0, "size must be nonzero");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6194
  HeapWord* next_block = addr + sz;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6195
  HeapWord* next_card  = (HeapWord*)round_to((uintptr_t)next_block,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6196
                                             CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6197
  assert(round_down((uintptr_t)addr,      CardTableModRefBS::card_size) <
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6198
         round_down((uintptr_t)next_card, CardTableModRefBS::card_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6199
         "must be different cards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6200
  return next_card;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6201
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6202
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6203
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6204
// CMS Bit Map Wrapper /////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6205
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6206
// Construct a CMS bit map infrastructure, but don't create the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6207
// bit vector itself. That is done by a separate call CMSBitMap::allocate()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6208
// further below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6209
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
  6210
  _bm(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6211
  _shifter(shifter),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6212
  _lock(mutex_rank >= 0 ? new Mutex(mutex_rank, mutex_name, true) : NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6213
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6214
  _bmStartWord = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6215
  _bmWordSize  = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6216
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6217
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6218
bool CMSBitMap::allocate(MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6219
  _bmStartWord = mr.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6220
  _bmWordSize  = mr.word_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6221
  ReservedSpace brs(ReservedSpace::allocation_align_size_up(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6222
                     (_bmWordSize >> (_shifter + LogBitsPerByte)) + 1));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6223
  if (!brs.is_reserved()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6224
    warning("CMS bit map allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6225
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6226
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6227
  // For now we'll just commit all of the bit map up fromt.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6228
  // Later on we'll try to be more parsimonious with swap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6229
  if (!_virtual_space.initialize(brs, brs.size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6230
    warning("CMS bit map backing store failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6231
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6232
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6233
  assert(_virtual_space.committed_size() == brs.size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6234
         "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
  6235
  _bm.set_map((BitMap::bm_word_t*)_virtual_space.low());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6236
  assert(_virtual_space.committed_size() << (_shifter + LogBitsPerByte) >=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6237
         _bmWordSize, "inconsistency in bit map sizing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6238
  _bm.set_size(_bmWordSize >> _shifter);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6239
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6240
  // bm.clear(); // can we rely on getting zero'd memory? verify below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6241
  assert(isAllClear(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6242
         "Expected zero'd memory from ReservedSpace constructor");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6243
  assert(_bm.size() == heapWordDiffToOffsetDiff(sizeInWords()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6244
         "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6245
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6246
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6247
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6248
void CMSBitMap::dirty_range_iterate_clear(MemRegion mr, MemRegionClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6249
  HeapWord *next_addr, *end_addr, *last_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6250
  assert_locked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6251
  assert(covers(mr), "out-of-range error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6252
  // XXX assert that start and end are appropriately aligned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6253
  for (next_addr = mr.start(), end_addr = mr.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6254
       next_addr < end_addr; next_addr = last_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6255
    MemRegion dirty_region = getAndClearMarkedRegion(next_addr, end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6256
    last_addr = dirty_region.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6257
    if (!dirty_region.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6258
      cl->do_MemRegion(dirty_region);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6259
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6260
      assert(last_addr == end_addr, "program logic");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6261
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6262
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6263
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6264
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6265
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6266
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6267
void CMSBitMap::assert_locked() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6268
  CMSLockVerifier::assert_locked(lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6269
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6270
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6271
bool CMSBitMap::covers(MemRegion mr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6272
  // assert(_bm.map() == _virtual_space.low(), "map inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6273
  assert((size_t)_bm.size() == (_bmWordSize >> _shifter),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6274
         "size inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6275
  return (mr.start() >= _bmStartWord) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6276
         (mr.end()   <= endWord());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6277
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6278
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6279
bool CMSBitMap::covers(HeapWord* start, size_t size) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6280
    return (start >= _bmStartWord && (start + size) <= endWord());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6281
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6283
void CMSBitMap::verifyNoOneBitsInRange(HeapWord* left, HeapWord* right) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6284
  // verify that there are no 1 bits in the interval [left, right)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6285
  FalseBitMapClosure falseBitMapClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6286
  iterate(&falseBitMapClosure, left, right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6287
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6288
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6289
void CMSBitMap::region_invariant(MemRegion mr)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6290
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6291
  assert_locked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6292
  // mr = mr.intersection(MemRegion(_bmStartWord, _bmWordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6293
  assert(!mr.is_empty(), "unexpected empty region");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6294
  assert(covers(mr), "mr should be covered by bit map");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6295
  // convert address range into offset range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6296
  size_t start_ofs = heapWordToOffset(mr.start());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6297
  // Make sure that end() is appropriately aligned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6298
  assert(mr.end() == (HeapWord*)round_to((intptr_t)mr.end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6299
                        (1 << (_shifter+LogHeapWordSize))),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6300
         "Misaligned mr.end()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6301
  size_t end_ofs   = heapWordToOffset(mr.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6302
  assert(end_ofs > start_ofs, "Should mark at least one bit");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6303
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6304
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6305
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6306
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6307
bool CMSMarkStack::allocate(size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6308
  // allocate a stack of the requisite depth
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6309
  ReservedSpace rs(ReservedSpace::allocation_align_size_up(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6310
                   size * sizeof(oop)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6311
  if (!rs.is_reserved()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6312
    warning("CMSMarkStack allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6313
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6314
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6315
  if (!_virtual_space.initialize(rs, rs.size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6316
    warning("CMSMarkStack backing store failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6317
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6318
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6319
  assert(_virtual_space.committed_size() == rs.size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6320
         "didn't reserve backing store for all of CMS stack?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6321
  _base = (oop*)(_virtual_space.low());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6322
  _index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6323
  _capacity = size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6324
  NOT_PRODUCT(_max_depth = 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6325
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6326
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6327
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6328
// XXX FIX ME !!! In the MT case we come in here holding a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6329
// leaf lock. For printing we need to take a further lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6330
// which has lower rank. We need to recallibrate the two
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6331
// lock-ranks involved in order to be able to rpint the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6332
// messages below. (Or defer the printing to the caller.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6333
// For now we take the expedient path of just disabling the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6334
// messages for the problematic case.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6335
void CMSMarkStack::expand() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6336
  assert(_capacity <= CMSMarkStackSizeMax, "stack bigger than permitted");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6337
  if (_capacity == CMSMarkStackSizeMax) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6338
    if (_hit_limit++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6339
      // We print a warning message only once per CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6340
      gclog_or_tty->print_cr(" (benign) Hit CMSMarkStack max size limit");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6341
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6342
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6343
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6344
  // Double capacity if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6345
  size_t new_capacity = MIN2(_capacity*2, CMSMarkStackSizeMax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6346
  // Do not give up existing stack until we have managed to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6347
  // get the double capacity that we desired.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6348
  ReservedSpace rs(ReservedSpace::allocation_align_size_up(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6349
                   new_capacity * sizeof(oop)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6350
  if (rs.is_reserved()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6351
    // Release the backing store associated with old stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6352
    _virtual_space.release();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6353
    // Reinitialize virtual space for new stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6354
    if (!_virtual_space.initialize(rs, rs.size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6355
      fatal("Not enough swap for expanded marking stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6356
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6357
    _base = (oop*)(_virtual_space.low());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6358
    _index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6359
    _capacity = new_capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6360
  } else if (_failed_double++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6361
    // Failed to double capacity, continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6362
    // we print a detail message only once per CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6363
    gclog_or_tty->print(" (benign) Failed to expand marking stack from "SIZE_FORMAT"K to "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6364
            SIZE_FORMAT"K",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6365
            _capacity / K, new_capacity / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6366
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6367
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6368
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6369
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6370
// Closures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6371
// XXX: there seems to be a lot of code  duplication here;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6372
// should refactor and consolidate common code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6373
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6374
// This closure is used to mark refs into the CMS generation in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6375
// the CMS bit map. Called at the first checkpoint. This closure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6376
// assumes that we do not need to re-mark dirty cards; if the CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6377
// generation on which this is used is not an oldest (modulo perm gen)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6378
// generation then this will lose younger_gen cards!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6379
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6380
MarkRefsIntoClosure::MarkRefsIntoClosure(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6381
  MemRegion span, CMSBitMap* bitMap, bool should_do_nmethods):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6382
    _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6383
    _bitMap(bitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6384
    _should_do_nmethods(should_do_nmethods)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6385
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6386
    assert(_ref_processor == NULL, "deliberately left NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6387
    assert(_bitMap->covers(_span), "_bitMap/_span mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6388
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6389
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6390
void MarkRefsIntoClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6391
  // 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
  6392
  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
  6393
  HeapWord* addr = (HeapWord*)obj;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6394
  if (_span.contains(addr)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6395
    // 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
  6396
    _bitMap->mark(addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6397
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6398
}
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6399
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6400
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
  6401
void MarkRefsIntoClosure::do_oop(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6402
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6403
// A variant of the above, used for CMS marking verification.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6404
MarkRefsIntoVerifyClosure::MarkRefsIntoVerifyClosure(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6405
  MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6406
  bool should_do_nmethods):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6407
    _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6408
    _verification_bm(verification_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6409
    _cms_bm(cms_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6410
    _should_do_nmethods(should_do_nmethods) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6411
    assert(_ref_processor == NULL, "deliberately left NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6412
    assert(_verification_bm->covers(_span), "_verification_bm/_span mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6413
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6414
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6415
void MarkRefsIntoVerifyClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6416
  // 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
  6417
  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
  6418
  HeapWord* addr = (HeapWord*)obj;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6419
  if (_span.contains(addr)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6420
    _verification_bm->mark(addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6421
    if (!_cms_bm->isMarked(addr)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6422
      oop(addr)->print();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6423
      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
  6424
      fatal("... aborting");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6425
    }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6426
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6427
}
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6428
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6429
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
  6430
void MarkRefsIntoVerifyClosure::do_oop(narrowOop* p) { MarkRefsIntoVerifyClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6431
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6432
//////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6433
// MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6434
//////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6435
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6436
MarkRefsIntoAndScanClosure::MarkRefsIntoAndScanClosure(MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6437
                                                       ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6438
                                                       CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6439
                                                       CMSBitMap* mod_union_table,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6440
                                                       CMSMarkStack*  mark_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6441
                                                       CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6442
                                                       CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6443
                                                       bool should_yield,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6444
                                                       bool concurrent_precleaning):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6445
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6446
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6447
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6448
  _mark_stack(mark_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6449
  _pushAndMarkClosure(collector, span, rp, bit_map, mod_union_table,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6450
                      mark_stack, revisit_stack, concurrent_precleaning),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6451
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6452
  _concurrent_precleaning(concurrent_precleaning),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6453
  _freelistLock(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6454
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6455
  _ref_processor = rp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6456
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6457
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6458
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6459
// This closure is used to mark refs into the CMS generation at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6460
// second (final) checkpoint, and to scan and transitively follow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6461
// the unmarked oops. It is also used during the concurrent precleaning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6462
// phase while scanning objects on dirty cards in the CMS generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6463
// The marks are made in the marking bit map and the marking stack is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6464
// used for keeping the (newly) grey objects during the scan.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6465
// 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
  6466
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
  6467
  if (obj != NULL) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6468
    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
  6469
    HeapWord* addr = (HeapWord*)obj;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6470
    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
  6471
    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
  6472
           "overflow list should be empty");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6473
    if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6474
        !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6475
      // mark bit map (object is now grey)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6476
      _bit_map->mark(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6477
      // push on marking stack (stack should be empty), and drain the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6478
      // stack by applying this closure to the oops in the oops popped
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6479
      // 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
  6480
      bool res = _mark_stack->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6481
      assert(res, "Should have space to push on empty stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6482
      do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6483
        oop new_oop = _mark_stack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6484
        assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6485
        assert(new_oop->is_parsable(), "Found unparsable oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6486
        assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6487
               "only grey objects on this stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6488
        // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6489
        // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6490
        new_oop->oop_iterate(&_pushAndMarkClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6491
        // check if it's time to yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6492
        do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6493
      } while (!_mark_stack->isEmpty() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6494
               (!_concurrent_precleaning && take_from_overflow_list()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6495
        // if marking stack is empty, and we are not doing this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6496
        // during precleaning, then check the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6497
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6498
    assert(_mark_stack->isEmpty(), "post-condition (eager drainage)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6499
    assert(_collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6500
           "overflow list was drained above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6501
    // We could restore evacuated mark words, if any, used for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6502
    // overflow list links here because the overflow list is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6503
    // provably empty here. That would reduce the maximum
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6504
    // size requirements for preserved_{oop,mark}_stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6505
    // But we'll just postpone it until we are all done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6506
    // so we can just stream through.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6507
    if (!_concurrent_precleaning && CMSOverflowEarlyRestoration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6508
      _collector->restore_preserved_marks_if_any();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6509
      assert(_collector->no_preserved_marks(), "No preserved marks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6510
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6511
    assert(!CMSOverflowEarlyRestoration || _collector->no_preserved_marks(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6512
           "All preserved marks should have been restored above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6513
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6514
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6515
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6516
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
  6517
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
  6518
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6519
void MarkRefsIntoAndScanClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6520
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6521
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6522
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6523
  assert_lock_strong(_bit_map->lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6524
  // relinquish the free_list_lock and bitMaplock()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6525
  _bit_map->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6526
  _freelistLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6527
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6528
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6529
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6530
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6531
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6532
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6533
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6534
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6536
  // 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
  6537
  for (unsigned i = 0;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6538
       i < CMSYieldSleepCount &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6539
       ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6540
       !CMSCollector::foregroundGCIsActive();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6541
       ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6542
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6543
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6544
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6545
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6546
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6547
  _freelistLock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6548
  _bit_map->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6549
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6550
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6551
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6552
///////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6553
// Par_MarkRefsIntoAndScanClosure: a parallel version of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6554
//                                 MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6555
///////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6556
Par_MarkRefsIntoAndScanClosure::Par_MarkRefsIntoAndScanClosure(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6557
  CMSCollector* collector, MemRegion span, ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6558
  CMSBitMap* bit_map, OopTaskQueue* work_queue, CMSMarkStack*  revisit_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6559
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6560
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6561
  _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6562
  _low_water_mark(MIN2((uint)(work_queue->max_elems()/4),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6563
                       (uint)(CMSWorkQueueDrainThreshold * ParallelGCThreads))),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6564
  _par_pushAndMarkClosure(collector, span, rp, bit_map, work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6565
                          revisit_stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6566
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6567
  _ref_processor = rp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6568
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6569
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6570
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6571
// This closure is used to mark refs into the CMS generation at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6572
// second (final) checkpoint, and to scan and transitively follow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6573
// the unmarked oops. The marks are made in the marking bit map and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6574
// the work_queue is used for keeping the (newly) grey objects during
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6575
// the scan phase whence they are also available for stealing by parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6576
// threads. Since the marking bit map is shared, updates are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6577
// synchronized (via CAS).
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6578
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
  6579
  if (obj != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6580
    // Ignore mark word because this could be an already marked oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6581
    // 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
  6582
    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
  6583
    HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6584
    if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6585
        !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6586
      // mark bit map (object will become grey):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6587
      // It is possible for several threads to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6588
      // trying to "claim" this object concurrently;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6589
      // the unique thread that succeeds in marking the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6590
      // object first will do the subsequent push on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6591
      // to the work queue (or overflow list).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6592
      if (_bit_map->par_mark(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6593
        // push on work_queue (which may not be empty), and trim the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6594
        // queue to an appropriate length by applying this closure to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6595
        // the oops in the oops popped from the stack (i.e. blacken the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6596
        // grey objects)
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6597
        bool res = _work_queue->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6598
        assert(res, "Low water mark should be less than capacity?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6599
        trim_queue(_low_water_mark);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6600
      } // Else, another thread claimed the object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6601
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6602
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6603
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6604
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6605
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
  6606
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
  6607
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6608
// This closure is used to rescan the marked objects on the dirty cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6609
// in the mod union table and the card table proper.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6610
size_t ScanMarkedObjectsAgainCarefullyClosure::do_object_careful_m(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6611
  oop p, MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6612
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6613
  size_t size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6614
  HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6615
  DEBUG_ONLY(_collector->verify_work_stacks_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6616
  assert(_span.contains(addr), "we are scanning the CMS generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6617
  // check if it's time to yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6618
  if (do_yield_check()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6619
    // We yielded for some foreground stop-world work,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6620
    // and we have been asked to abort this ongoing preclean cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6621
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6622
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6623
  if (_bitMap->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6624
    // it's marked; is it potentially uninitialized?
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6625
    if (p->klass_or_null() != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6626
      if (CMSPermGenPrecleaningEnabled && !p->is_parsable()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6627
        // Signal precleaning to redirty the card since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6628
        // the klass pointer is already installed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6629
        assert(size == 0, "Initial value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6630
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6631
        assert(p->is_parsable(), "must be parsable.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6632
        // an initialized object; ignore mark word in verification below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6633
        // since we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6634
        assert(p->is_oop(true), "should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6635
        if (p->is_objArray()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6636
          // objArrays are precisely marked; restrict scanning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6637
          // to dirty cards only.
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6638
          size = CompactibleFreeListSpace::adjustObjectSize(
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6639
                   p->oop_iterate(_scanningClosure, mr));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6640
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6641
          // A non-array may have been imprecisely marked; we need
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6642
          // to scan object in its entirety.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6643
          size = CompactibleFreeListSpace::adjustObjectSize(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6644
                   p->oop_iterate(_scanningClosure));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6645
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6646
        #ifdef DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6647
          size_t direct_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6648
            CompactibleFreeListSpace::adjustObjectSize(p->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6649
          assert(size == direct_size, "Inconsistency in size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6650
          assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6651
          if (!_bitMap->isMarked(addr+1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6652
            _bitMap->verifyNoOneBitsInRange(addr+2, addr+size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6653
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6654
            _bitMap->verifyNoOneBitsInRange(addr+2, addr+size-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6655
            assert(_bitMap->isMarked(addr+size-1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6656
                   "inconsistent Printezis mark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6657
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6658
        #endif // DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6659
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6660
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6661
      // an unitialized object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6662
      assert(_bitMap->isMarked(addr+1), "missing Printezis mark?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6663
      HeapWord* nextOneAddr = _bitMap->getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6664
      size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6665
      assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6666
             "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6667
      // Note that pre-cleaning needn't redirty the card. OopDesc::set_klass()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6668
      // will dirty the card when the klass pointer is installed in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6669
      // object (signalling the completion of initialization).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6670
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6671
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6672
    // Either a not yet marked object or an uninitialized object
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6673
    if (p->klass_or_null() == NULL || !p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6674
      // An uninitialized object, skip to the next card, since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6675
      // we may not be able to read its P-bits yet.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6676
      assert(size == 0, "Initial value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6677
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6678
      // An object not (yet) reached by marking: we merely need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6679
      // compute its size so as to go look at the next block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6680
      assert(p->is_oop(true), "should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6681
      size = CompactibleFreeListSpace::adjustObjectSize(p->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6682
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6683
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6684
  DEBUG_ONLY(_collector->verify_work_stacks_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6685
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6686
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6687
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6688
void ScanMarkedObjectsAgainCarefullyClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6689
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6690
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6691
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6692
  assert_lock_strong(_bitMap->lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6693
  // relinquish the free_list_lock and bitMaplock()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6694
  _bitMap->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6695
  _freelistLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6696
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6697
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6698
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6699
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6700
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6701
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6702
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6703
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6704
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6705
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6706
  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
  6707
                   ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6708
                   !CMSCollector::foregroundGCIsActive(); ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6709
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6710
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6711
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6712
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6713
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6714
  _freelistLock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6715
  _bitMap->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6716
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6717
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6718
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6719
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6720
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6721
// SurvivorSpacePrecleanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6722
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6723
// This (single-threaded) closure is used to preclean the oops in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6724
// the survivor spaces.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6725
size_t SurvivorSpacePrecleanClosure::do_object_careful(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6726
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6727
  HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6728
  DEBUG_ONLY(_collector->verify_work_stacks_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6729
  assert(!_span.contains(addr), "we are scanning the survivor spaces");
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6730
  assert(p->klass_or_null() != NULL, "object should be initializd");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6731
  assert(p->is_parsable(), "must be parsable.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6732
  // an initialized object; ignore mark word in verification below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6733
  // since we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6734
  assert(p->is_oop(true), "should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6735
  // Note that we do not yield while we iterate over
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6736
  // the interior oops of p, pushing the relevant ones
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6737
  // on our marking stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6738
  size_t size = p->oop_iterate(_scanning_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6739
  do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6740
  // Observe that below, we do not abandon the preclean
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6741
  // phase as soon as we should; rather we empty the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6742
  // marking stack before returning. This is to satisfy
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6743
  // some existing assertions. In general, it may be a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6744
  // good idea to abort immediately and complete the marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6745
  // from the grey objects at a later time.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6746
  while (!_mark_stack->isEmpty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6747
    oop new_oop = _mark_stack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6748
    assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6749
    assert(new_oop->is_parsable(), "Found unparsable oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6750
    assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6751
           "only grey objects on this stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6752
    // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6753
    // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6754
    new_oop->oop_iterate(_scanning_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6755
    // check if it's time to yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6756
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6757
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6758
  unsigned int after_count =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6759
    GenCollectedHeap::heap()->total_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6760
  bool abort = (_before_count != after_count) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6761
               _collector->should_abort_preclean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6762
  return abort ? 0 : size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6763
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6764
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6765
void SurvivorSpacePrecleanClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6766
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6767
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6768
  assert_lock_strong(_bit_map->lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6769
  // Relinquish the bit map lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6770
  _bit_map->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6771
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6772
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6773
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6774
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6775
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6776
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6777
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6778
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6779
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6780
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6781
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6782
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6783
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6784
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6785
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6786
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6787
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6788
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6789
  _bit_map->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6790
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6791
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6792
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6793
// This closure is used to rescan the marked objects on the dirty cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6794
// in the mod union table and the card table proper. In the parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6795
// case, although the bitMap is shared, we do a single read so the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6796
// isMarked() query is "safe".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6797
bool ScanMarkedObjectsAgainClosure::do_object_bm(oop p, MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6798
  // Ignore mark word because we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6799
  assert(p->is_oop_or_null(true), "expected an oop or null");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6800
  HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6801
  assert(_span.contains(addr), "we are scanning the CMS generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6802
  bool is_obj_array = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6803
  #ifdef DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6804
    if (!_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6805
      assert(_mark_stack->isEmpty(), "pre-condition (eager drainage)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6806
      assert(_collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6807
             "overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6808
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6809
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6810
  #endif // DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6811
  if (_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6812
    // Obj arrays are precisely marked, non-arrays are not;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6813
    // so we scan objArrays precisely and non-arrays in their
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6814
    // entirety.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6815
    if (p->is_objArray()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6816
      is_obj_array = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6817
      if (_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6818
        p->oop_iterate(_par_scan_closure, mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6819
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6820
        p->oop_iterate(_scan_closure, mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6821
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6822
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6823
      if (_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6824
        p->oop_iterate(_par_scan_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6825
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6826
        p->oop_iterate(_scan_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6827
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6828
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6829
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6830
  #ifdef DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6831
    if (!_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6832
      assert(_mark_stack->isEmpty(), "post-condition (eager drainage)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6833
      assert(_collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6834
             "overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6835
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6836
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6837
  #endif // DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6838
  return is_obj_array;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6839
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6840
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6841
MarkFromRootsClosure::MarkFromRootsClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6842
                        MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6843
                        CMSBitMap* bitMap, CMSMarkStack*  markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6844
                        CMSMarkStack*  revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6845
                        bool should_yield, bool verifying):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6846
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6847
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6848
  _bitMap(bitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6849
  _mut(&collector->_modUnionTable),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6850
  _markStack(markStack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6851
  _revisitStack(revisitStack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6852
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6853
  _skipBits(0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6854
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6855
  assert(_markStack->isEmpty(), "stack should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6856
  _finger = _bitMap->startWord();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6857
  _threshold = _finger;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6858
  assert(_collector->_restart_addr == NULL, "Sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6859
  assert(_span.contains(_finger), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6860
  DEBUG_ONLY(_verifying = verifying;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6861
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6862
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6863
void MarkFromRootsClosure::reset(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6864
  assert(_markStack->isEmpty(), "would cause duplicates on stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6865
  assert(_span.contains(addr), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6866
  _finger = addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6867
  _threshold = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6868
                 (intptr_t)_finger, CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6869
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6870
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6871
// Should revisit to see if this should be restructured for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6872
// greater efficiency.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  6873
bool MarkFromRootsClosure::do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6874
  if (_skipBits > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6875
    _skipBits--;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  6876
    return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6877
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6878
  // convert offset into a HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6879
  HeapWord* addr = _bitMap->startWord() + offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6880
  assert(_bitMap->endWord() && addr < _bitMap->endWord(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6881
         "address out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6882
  assert(_bitMap->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6883
  if (_bitMap->isMarked(addr+1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6884
    // this is an allocated but not yet initialized object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6885
    assert(_skipBits == 0, "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6886
    _skipBits = 2;  // skip next two marked bits ("Printezis-marks")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6887
    oop p = oop(addr);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6888
    if (p->klass_or_null() == NULL || !p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6889
      DEBUG_ONLY(if (!_verifying) {)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6890
        // We re-dirty the cards on which this object lies and increase
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6891
        // the _threshold so that we'll come back to scan this object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6892
        // during the preclean or remark phase. (CMSCleanOnEnter)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6893
        if (CMSCleanOnEnter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6894
          size_t sz = _collector->block_size_using_printezis_bits(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6895
          HeapWord* end_card_addr   = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6896
                                         (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
  6897
          MemRegion redirty_range = MemRegion(addr, end_card_addr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6898
          assert(!redirty_range.is_empty(), "Arithmetical tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6899
          // Bump _threshold to end_card_addr; note that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6900
          // _threshold cannot possibly exceed end_card_addr, anyhow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6901
          // This prevents future clearing of the card as the scan proceeds
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6902
          // to the right.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6903
          assert(_threshold <= end_card_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6904
                 "Because we are just scanning into this object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6905
          if (_threshold < end_card_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6906
            _threshold = end_card_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6907
          }
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6908
          if (p->klass_or_null() != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6909
            // Redirty the range of cards...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6910
            _mut->mark_range(redirty_range);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6911
          } // ...else the setting of klass will dirty the card anyway.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6912
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6913
      DEBUG_ONLY(})
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  6914
      return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6915
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6916
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6917
  scanOopsInOop(addr);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  6918
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6919
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6920
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6921
// We take a break if we've been at this for a while,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6922
// so as to avoid monopolizing the locks involved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6923
void MarkFromRootsClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6924
  // First give up the locks, then yield, then re-lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6925
  // We should probably use a constructor/destructor idiom to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6926
  // do this unlock/lock or modify the MutexUnlocker class to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6927
  // serve our purpose. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6928
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6929
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6930
  assert_lock_strong(_bitMap->lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6931
  _bitMap->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6932
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6933
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6934
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6935
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6936
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6937
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6938
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6939
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6940
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6941
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6942
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6943
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6944
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6945
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6946
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6947
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6948
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6949
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6950
  _bitMap->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6951
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6952
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6953
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6954
void MarkFromRootsClosure::scanOopsInOop(HeapWord* ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6955
  assert(_bitMap->isMarked(ptr), "expected bit to be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6956
  assert(_markStack->isEmpty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6957
         "should drain stack to limit stack usage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6958
  // 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
  6959
  oop obj = oop(ptr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6960
  // Ignore mark word in verification below, since we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6961
  // 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
  6962
  assert(obj->is_oop(true), "should be an oop");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6963
  assert(_finger <= ptr, "_finger runneth ahead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6964
  // 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
  6965
  _finger = ptr + obj->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6966
  assert(_finger > ptr, "we just incremented it above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6967
  // On large heaps, it may take us some time to get through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6968
  // the marking phase (especially if running iCMS). During
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6969
  // this time it's possible that a lot of mutations have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6970
  // accumulated in the card table and the mod union table --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6971
  // these mutation records are redundant until we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6972
  // actually traced into the corresponding card.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6973
  // Here, we check whether advancing the finger would make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6974
  // us cross into a new card, and if so clear corresponding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6975
  // cards in the MUT (preclean them in the card-table in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6976
  // future).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6977
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6978
  DEBUG_ONLY(if (!_verifying) {)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6979
    // The clean-on-enter optimization is disabled by default,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6980
    // until we fix 6178663.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6981
    if (CMSCleanOnEnter && (_finger > _threshold)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6982
      // [_threshold, _finger) represents the interval
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6983
      // of cards to be cleared  in MUT (or precleaned in card table).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6984
      // The set of cards to be cleared is all those that overlap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6985
      // with the interval [_threshold, _finger); note that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6986
      // _threshold is always kept card-aligned but _finger isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6987
      // always card-aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6988
      HeapWord* old_threshold = _threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6989
      assert(old_threshold == (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6990
              (intptr_t)old_threshold, CardTableModRefBS::card_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6991
             "_threshold should always be card-aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6992
      _threshold = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6993
                     (intptr_t)_finger, CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6994
      MemRegion mr(old_threshold, _threshold);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6995
      assert(!mr.is_empty(), "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6996
      assert(_span.contains(mr), "Should clear within span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6997
      // XXX When _finger crosses from old gen into perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6998
      // we may be doing unnecessary cleaning; do better in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6999
      // future by detecting that condition and clearing fewer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7000
      // MUT/CT entries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7001
      _mut->clear_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7002
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7003
  DEBUG_ONLY(})
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7004
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7005
  // Note: the finger doesn't advance while we drain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7006
  // the stack below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7007
  PushOrMarkClosure pushOrMarkClosure(_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7008
                                      _span, _bitMap, _markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7009
                                      _revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7010
                                      _finger, this);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7011
  bool res = _markStack->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7012
  assert(res, "Empty non-zero size stack should have space for single push");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7013
  while (!_markStack->isEmpty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7014
    oop new_oop = _markStack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7015
    // Skip verifying header mark word below because we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7016
    // running concurrent with mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7017
    assert(new_oop->is_oop(true), "Oops! expected to pop an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7018
    // now scan this oop's oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7019
    new_oop->oop_iterate(&pushOrMarkClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7020
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7021
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7022
  assert(_markStack->isEmpty(), "tautology, emphasizing post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7023
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7024
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7025
Par_MarkFromRootsClosure::Par_MarkFromRootsClosure(CMSConcMarkingTask* task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7026
                       CMSCollector* collector, MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7027
                       CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7028
                       OopTaskQueue* work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7029
                       CMSMarkStack*  overflow_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7030
                       CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7031
                       bool should_yield):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7032
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7033
  _whole_span(collector->_span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7034
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7035
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7036
  _mut(&collector->_modUnionTable),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7037
  _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7038
  _overflow_stack(overflow_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7039
  _revisit_stack(revisit_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7040
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7041
  _skip_bits(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7042
  _task(task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7043
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7044
  assert(_work_queue->size() == 0, "work_queue should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7045
  _finger = span.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7046
  _threshold = _finger;     // XXX Defer clear-on-enter optimization for now
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7047
  assert(_span.contains(_finger), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7048
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7049
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7050
// Should revisit to see if this should be restructured for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7051
// greater efficiency.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7052
bool Par_MarkFromRootsClosure::do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7053
  if (_skip_bits > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7054
    _skip_bits--;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7055
    return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7056
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7057
  // convert offset into a HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7058
  HeapWord* addr = _bit_map->startWord() + offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7059
  assert(_bit_map->endWord() && addr < _bit_map->endWord(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7060
         "address out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7061
  assert(_bit_map->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7062
  if (_bit_map->isMarked(addr+1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7063
    // this is an allocated object that might not yet be initialized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7064
    assert(_skip_bits == 0, "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7065
    _skip_bits = 2;  // skip next two marked bits ("Printezis-marks")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7066
    oop p = oop(addr);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  7067
    if (p->klass_or_null() == NULL || !p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7068
      // in the case of Clean-on-Enter optimization, redirty card
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7069
      // and avoid clearing card by increasing  the threshold.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7070
      return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7071
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7072
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7073
  scan_oops_in_oop(addr);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7074
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7075
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7076
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7077
void Par_MarkFromRootsClosure::scan_oops_in_oop(HeapWord* ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7078
  assert(_bit_map->isMarked(ptr), "expected bit to be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7079
  // Should we assert that our work queue is empty or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7080
  // below some drain limit?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7081
  assert(_work_queue->size() == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7082
         "should drain stack to limit stack usage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7083
  // 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
  7084
  oop obj = oop(ptr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7085
  // Ignore mark word in verification below, since we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7086
  // 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
  7087
  assert(obj->is_oop(true), "should be an oop");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7088
  assert(_finger <= ptr, "_finger runneth ahead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7089
  // 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
  7090
  _finger = ptr + obj->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7091
  assert(_finger > ptr, "we just incremented it above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7092
  // On large heaps, it may take us some time to get through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7093
  // the marking phase (especially if running iCMS). During
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7094
  // this time it's possible that a lot of mutations have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7095
  // accumulated in the card table and the mod union table --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7096
  // these mutation records are redundant until we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7097
  // actually traced into the corresponding card.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7098
  // Here, we check whether advancing the finger would make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7099
  // us cross into a new card, and if so clear corresponding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7100
  // cards in the MUT (preclean them in the card-table in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7101
  // future).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7102
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7103
  // The clean-on-enter optimization is disabled by default,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7104
  // until we fix 6178663.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7105
  if (CMSCleanOnEnter && (_finger > _threshold)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7106
    // [_threshold, _finger) represents the interval
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7107
    // of cards to be cleared  in MUT (or precleaned in card table).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7108
    // The set of cards to be cleared is all those that overlap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7109
    // with the interval [_threshold, _finger); note that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7110
    // _threshold is always kept card-aligned but _finger isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7111
    // always card-aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7112
    HeapWord* old_threshold = _threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7113
    assert(old_threshold == (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7114
            (intptr_t)old_threshold, CardTableModRefBS::card_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7115
           "_threshold should always be card-aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7116
    _threshold = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7117
                   (intptr_t)_finger, CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7118
    MemRegion mr(old_threshold, _threshold);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7119
    assert(!mr.is_empty(), "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7120
    assert(_span.contains(mr), "Should clear within span"); // _whole_span ??
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7121
    // XXX When _finger crosses from old gen into perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7122
    // we may be doing unnecessary cleaning; do better in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7123
    // future by detecting that condition and clearing fewer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7124
    // MUT/CT entries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7125
    _mut->clear_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7126
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7127
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7128
  // Note: the local finger doesn't advance while we drain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7129
  // the stack below, but the global finger sure can and will.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7130
  HeapWord** gfa = _task->global_finger_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7131
  Par_PushOrMarkClosure pushOrMarkClosure(_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7132
                                      _span, _bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7133
                                      _work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7134
                                      _overflow_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7135
                                      _revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7136
                                      _finger,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7137
                                      gfa, this);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7138
  bool res = _work_queue->push(obj);   // overflow could occur here
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7139
  assert(res, "Will hold once we use workqueues");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7140
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7141
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7142
    if (!_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7143
      // We emptied our work_queue; check if there's stuff that can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7144
      // be gotten from the overflow stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7145
      if (CMSConcMarkingTask::get_work_from_overflow_stack(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7146
            _overflow_stack, _work_queue)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7147
        do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7148
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7149
      } else {  // done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7150
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7151
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7152
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7153
    // Skip verifying header mark word below because we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7154
    // running concurrent with mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7155
    assert(new_oop->is_oop(true), "Oops! expected to pop an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7156
    // now scan this oop's oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7157
    new_oop->oop_iterate(&pushOrMarkClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7158
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7159
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7160
  assert(_work_queue->size() == 0, "tautology, emphasizing post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7161
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7162
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7163
// Yield in response to a request from VM Thread or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7164
// from mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7165
void Par_MarkFromRootsClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7166
  assert(_task != NULL, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7167
  _task->yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7168
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7169
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7170
// A variant of the above used for verifying CMS marking work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7171
MarkFromRootsVerifyClosure::MarkFromRootsVerifyClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7172
                        MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7173
                        CMSBitMap* verification_bm, CMSBitMap* cms_bm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7174
                        CMSMarkStack*  mark_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7175
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7176
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7177
  _verification_bm(verification_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7178
  _cms_bm(cms_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7179
  _mark_stack(mark_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7180
  _pam_verify_closure(collector, span, verification_bm, cms_bm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7181
                      mark_stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7182
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7183
  assert(_mark_stack->isEmpty(), "stack should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7184
  _finger = _verification_bm->startWord();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7185
  assert(_collector->_restart_addr == NULL, "Sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7186
  assert(_span.contains(_finger), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7187
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7188
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7189
void MarkFromRootsVerifyClosure::reset(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7190
  assert(_mark_stack->isEmpty(), "would cause duplicates on stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7191
  assert(_span.contains(addr), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7192
  _finger = addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7193
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7194
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7195
// Should revisit to see if this should be restructured for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7196
// greater efficiency.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7197
bool MarkFromRootsVerifyClosure::do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7198
  // convert offset into a HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7199
  HeapWord* addr = _verification_bm->startWord() + offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7200
  assert(_verification_bm->endWord() && addr < _verification_bm->endWord(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7201
         "address out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7202
  assert(_verification_bm->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7203
  assert(_cms_bm->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7204
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7205
  assert(_mark_stack->isEmpty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7206
         "should drain stack to limit stack usage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7207
  // 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
  7208
  oop obj = oop(addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7209
  assert(obj->is_oop(), "should be an oop");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7210
  assert(_finger <= addr, "_finger runneth ahead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7211
  // 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
  7212
  _finger = addr + obj->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7213
  assert(_finger > addr, "we just incremented it above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7214
  // Note: the finger doesn't advance while we drain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7215
  // the stack below.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7216
  bool res = _mark_stack->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7217
  assert(res, "Empty non-zero size stack should have space for single push");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7218
  while (!_mark_stack->isEmpty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7219
    oop new_oop = _mark_stack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7220
    assert(new_oop->is_oop(), "Oops! expected to pop an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7221
    // now scan this oop's oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7222
    new_oop->oop_iterate(&_pam_verify_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7223
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7224
  assert(_mark_stack->isEmpty(), "tautology, emphasizing post-condition");
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7225
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7226
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7227
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7228
PushAndMarkVerifyClosure::PushAndMarkVerifyClosure(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7229
  CMSCollector* collector, MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7230
  CMSBitMap* verification_bm, CMSBitMap* cms_bm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7231
  CMSMarkStack*  mark_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7232
  OopClosure(collector->ref_processor()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7233
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7234
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7235
  _verification_bm(verification_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7236
  _cms_bm(cms_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7237
  _mark_stack(mark_stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7238
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7239
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7240
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
  7241
void PushAndMarkVerifyClosure::do_oop(narrowOop* p) { PushAndMarkVerifyClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7242
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7243
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7244
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7245
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7246
void PushAndMarkVerifyClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7247
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7248
  HeapWord* ra = (HeapWord*)_mark_stack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7249
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7250
  _mark_stack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7251
  _mark_stack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7252
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7253
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7254
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
  7255
  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
  7256
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7257
  if (_span.contains(addr) && !_verification_bm->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7258
    // Oop lies in _span and isn't yet grey or black
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7259
    _verification_bm->mark(addr);            // now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7260
    if (!_cms_bm->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7261
      oop(addr)->print();
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7262
      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
  7263
                             addr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7264
      fatal("... aborting");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7265
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7266
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7267
    if (!_mark_stack->push(obj)) { // stack overflow
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7268
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7269
        gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7270
                               SIZE_FORMAT, _mark_stack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7271
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7272
      assert(_mark_stack->isFull(), "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7273
      handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7274
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7275
    // anything including and to the right of _finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7276
    // will be scanned as we iterate over the remainder of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7277
    // bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7278
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7279
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7280
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7281
PushOrMarkClosure::PushOrMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7282
                     MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7283
                     CMSBitMap* bitMap, CMSMarkStack*  markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7284
                     CMSMarkStack*  revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7285
                     HeapWord* finger, MarkFromRootsClosure* parent) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7286
  OopClosure(collector->ref_processor()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7287
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7288
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7289
  _bitMap(bitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7290
  _markStack(markStack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7291
  _revisitStack(revisitStack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7292
  _finger(finger),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7293
  _parent(parent),
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  7294
  _should_remember_klasses(collector->should_unload_classes())
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7295
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7296
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7297
Par_PushOrMarkClosure::Par_PushOrMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7298
                     MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7299
                     CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7300
                     OopTaskQueue* work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7301
                     CMSMarkStack*  overflow_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7302
                     CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7303
                     HeapWord* finger,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7304
                     HeapWord** global_finger_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7305
                     Par_MarkFromRootsClosure* parent) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7306
  OopClosure(collector->ref_processor()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7307
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7308
  _whole_span(collector->_span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7309
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7310
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7311
  _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7312
  _overflow_stack(overflow_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7313
  _revisit_stack(revisit_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7314
  _finger(finger),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7315
  _global_finger_addr(global_finger_addr),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7316
  _parent(parent),
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  7317
  _should_remember_klasses(collector->should_unload_classes())
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7318
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7319
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  7320
// Assumes thread-safe access by callers, who are
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  7321
// responsible for mutual exclusion.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7322
void CMSCollector::lower_restart_addr(HeapWord* low) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7323
  assert(_span.contains(low), "Out of bounds addr");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7324
  if (_restart_addr == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7325
    _restart_addr = low;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7326
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7327
    _restart_addr = MIN2(_restart_addr, low);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7328
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7329
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7330
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7331
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7332
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7333
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7334
void PushOrMarkClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7335
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7336
  HeapWord* ra = (HeapWord*)_markStack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7337
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7338
  _markStack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7339
  _markStack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7340
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7341
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7342
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7343
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7344
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7345
void Par_PushOrMarkClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7346
  // 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
  7347
  // workers from interfering with the work done below.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7348
  MutexLockerEx ml(_overflow_stack->par_lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7349
                   Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7350
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7351
  HeapWord* ra = (HeapWord*)_overflow_stack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7352
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7353
  _overflow_stack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7354
  _overflow_stack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7355
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7356
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7357
void PushOrMarkClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7358
  // 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
  7359
  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
  7360
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7361
  if (_span.contains(addr) && !_bitMap->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7362
    // Oop lies in _span and isn't yet grey or black
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7363
    _bitMap->mark(addr);            // now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7364
    if (addr < _finger) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7365
      // the bit map iteration has already either passed, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7366
      // sampled, this bit in the bit map; we'll need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7367
      // use the marking stack to scan this oop's oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7368
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7369
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7370
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7371
            _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7372
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7373
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7374
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7375
      )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7376
      if (simulate_overflow || !_markStack->push(obj)) { // stack overflow
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7377
        if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7378
          gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7379
                                 SIZE_FORMAT, _markStack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7380
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7381
        assert(simulate_overflow || _markStack->isFull(), "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7382
        handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7383
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7384
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7385
    // anything including and to the right of _finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7386
    // will be scanned as we iterate over the remainder of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7387
    // bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7388
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7389
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7390
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7391
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7392
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
  7393
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
  7394
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7395
void Par_PushOrMarkClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7396
  // 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
  7397
  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
  7398
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7399
  if (_whole_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7400
    // Oop lies in _span and isn't yet grey or black
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7401
    // We read the global_finger (volatile read) strictly after marking oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7402
    bool res = _bit_map->par_mark(addr);    // now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7403
    volatile HeapWord** gfa = (volatile HeapWord**)_global_finger_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7404
    // Should we push this marked oop on our stack?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7405
    // -- if someone else marked it, nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7406
    // -- if target oop is above global finger nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7407
    // -- if target oop is in chunk and above local finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7408
    //      then nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7409
    // -- else push on work queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7410
    if (   !res       // someone else marked it, they will deal with it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7411
        || (addr >= *gfa)  // will be scanned in a later task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7412
        || (_span.contains(addr) && addr >= _finger)) { // later in this chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7413
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7414
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7415
    // the bit map iteration has already either passed, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7416
    // sampled, this bit in the bit map; we'll need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7417
    // use the marking stack to scan this oop's oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7418
    bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7419
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7420
      if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7421
          _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7422
        // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7423
        simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7424
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7425
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7426
    if (simulate_overflow ||
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7427
        !(_work_queue->push(obj) || _overflow_stack->par_push(obj))) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7428
      // stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7429
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7430
        gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7431
                               SIZE_FORMAT, _overflow_stack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7432
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7433
      // We cannot assert that the overflow stack is full because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7434
      // it may have been emptied since.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7435
      assert(simulate_overflow ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7436
             _work_queue->size() == _work_queue->max_elems(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7437
            "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7438
      handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7439
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7440
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7441
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7442
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7443
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7444
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
  7445
void Par_PushOrMarkClosure::do_oop(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7446
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7447
PushAndMarkClosure::PushAndMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7448
                                       MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7449
                                       ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7450
                                       CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7451
                                       CMSBitMap* mod_union_table,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7452
                                       CMSMarkStack*  mark_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7453
                                       CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7454
                                       bool           concurrent_precleaning):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7455
  OopClosure(rp),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7456
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7457
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7458
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7459
  _mod_union_table(mod_union_table),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7460
  _mark_stack(mark_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7461
  _revisit_stack(revisit_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7462
  _concurrent_precleaning(concurrent_precleaning),
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  7463
  _should_remember_klasses(collector->should_unload_classes())
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7464
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7465
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7466
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7467
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7468
// Grey object rescan during pre-cleaning and second checkpoint phases --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7469
// 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
  7470
void PushAndMarkClosure::do_oop(oop obj) {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7471
  // Ignore mark word verification. If during concurrent precleaning,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7472
  // the object monitor may be locked. If during the checkpoint
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7473
  // 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
  7474
  // 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
  7475
  // the mark word may be NULL).
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7476
  assert(obj->is_oop_or_null(true /* ignore mark word */),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7477
         "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
  7478
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7479
  // Check if oop points into the CMS generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7480
  // and is not marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7481
  if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7482
    // a white object ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7483
    _bit_map->mark(addr);         // ... now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7484
    // push on the marking stack (grey set)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7485
    bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7486
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7487
      if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7488
          _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7489
        // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7490
        simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7491
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7492
    )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7493
    if (simulate_overflow || !_mark_stack->push(obj)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7494
      if (_concurrent_precleaning) {
991
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7495
         // During precleaning we can just dirty the appropriate card(s)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7496
         // 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
  7497
         // 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
  7498
         // 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
  7499
         // 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
  7500
         // dirty cards.
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7501
         // 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
  7502
         // 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
  7503
         // are required.
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7504
         if (obj->is_objArray()) {
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7505
           size_t sz = obj->size();
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7506
           HeapWord* end_card_addr = (HeapWord*)round_to(
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7507
                                        (intptr_t)(addr+sz), CardTableModRefBS::card_size);
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7508
           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
  7509
           assert(!redirty_range.is_empty(), "Arithmetical tautology");
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7510
           _mod_union_table->mark_range(redirty_range);
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7511
         } else {
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7512
           _mod_union_table->mark(addr);
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7513
         }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7514
         _collector->_ser_pmc_preclean_ovflw++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7515
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7516
         // During the remark phase, we need to remember this oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7517
         // in the overflow list.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7518
         _collector->push_on_overflow_list(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7519
         _collector->_ser_pmc_remark_ovflw++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7520
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7521
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7522
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7523
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7524
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7525
Par_PushAndMarkClosure::Par_PushAndMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7526
                                               MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7527
                                               ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7528
                                               CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7529
                                               OopTaskQueue* work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7530
                                               CMSMarkStack* revisit_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7531
  OopClosure(rp),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7532
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7533
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7534
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7535
  _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7536
  _revisit_stack(revisit_stack),
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  7537
  _should_remember_klasses(collector->should_unload_classes())
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7538
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7539
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7540
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7541
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7542
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
  7543
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
  7544
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7545
// Grey object rescan during second checkpoint phase --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7546
// the parallel version.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7547
void Par_PushAndMarkClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7548
  // In the assert below, we ignore the mark word because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7549
  // this oop may point to an already visited object that is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7550
  // on the overflow stack (in which case the mark word has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7551
  // been hijacked for chaining into the overflow stack --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7552
  // if this is the last object in the overflow stack then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7553
  // its mark word will be NULL). Because this object may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7554
  // have been subsequently popped off the global overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7555
  // stack, and the mark word possibly restored to the prototypical
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7556
  // value, by the time we get to examined this failing assert in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7557
  // the debugger, is_oop_or_null(false) may subsequently start
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7558
  // to hold.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7559
  assert(obj->is_oop_or_null(true),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7560
         "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
  7561
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7562
  // Check if oop points into the CMS generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7563
  // and is not marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7564
  if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7565
    // a white object ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7566
    // If we manage to "claim" the object, by being the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7567
    // first thread to mark it, then we push it on our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7568
    // marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7569
    if (_bit_map->par_mark(addr)) {     // ... now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7570
      // push on work queue (grey set)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7571
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7572
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7573
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7574
            _collector->par_simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7575
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7576
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7577
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7578
      )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7579
      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
  7580
        _collector->par_push_on_overflow_list(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7581
        _collector->_par_pmc_remark_ovflw++; //  imprecise OK: no need to CAS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7582
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7583
    } // Else, some other thread got there first
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_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
  7588
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
  7589
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7590
void PushAndMarkClosure::remember_klass(Klass* k) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7591
  if (!_revisit_stack->push(oop(k))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7592
    fatal("Revisit stack overflowed in PushAndMarkClosure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7593
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7594
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7595
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7596
void Par_PushAndMarkClosure::remember_klass(Klass* k) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7597
  if (!_revisit_stack->par_push(oop(k))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7598
    fatal("Revist stack overflowed in Par_PushAndMarkClosure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7599
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7600
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7601
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7602
void CMSPrecleanRefsYieldClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7603
  Mutex* bml = _collector->bitMapLock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7604
  assert_lock_strong(bml);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7605
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7606
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7607
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7608
  bml->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7609
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7610
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7611
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7612
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7613
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7614
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7615
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7616
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7617
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7618
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7619
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7620
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7621
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7622
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7623
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7624
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7625
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7626
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7627
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7628
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7629
  bml->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7630
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7631
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7632
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7633
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7634
bool CMSPrecleanRefsYieldClosure::should_return() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7635
  if (ConcurrentMarkSweepThread::should_yield()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7636
    do_yield_work();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7637
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7638
  return _collector->foregroundGCIsActive();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7639
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7640
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7641
void MarkFromDirtyCardsClosure::do_MemRegion(MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7642
  assert(((size_t)mr.start())%CardTableModRefBS::card_size_in_words == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7643
         "mr should be aligned to start at a card boundary");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7644
  // We'd like to assert:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7645
  // assert(mr.word_size()%CardTableModRefBS::card_size_in_words == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7646
  //        "mr should be a range of cards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7647
  // However, that would be too strong in one case -- the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7648
  // partition ends at _unallocated_block which, in general, can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7649
  // an arbitrary boundary, not necessarily card aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7650
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7651
    _num_dirty_cards +=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7652
         mr.word_size()/CardTableModRefBS::card_size_in_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7653
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7654
  _space->object_iterate_mem(mr, &_scan_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7655
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7656
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7657
SweepClosure::SweepClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7658
                           ConcurrentMarkSweepGeneration* g,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7659
                           CMSBitMap* bitMap, bool should_yield) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7660
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7661
  _g(g),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7662
  _sp(g->cmsSpace()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7663
  _limit(_sp->sweep_limit()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7664
  _freelistLock(_sp->freelistLock()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7665
  _bitMap(bitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7666
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7667
  _inFreeRange(false),           // No free range at beginning of sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7668
  _freeRangeInFreeLists(false),  // No free range at beginning of sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7669
  _lastFreeRangeCoalesced(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7670
  _freeFinger(g->used_region().start())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7671
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7672
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7673
    _numObjectsFreed = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7674
    _numWordsFreed   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7675
    _numObjectsLive = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7676
    _numWordsLive = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7677
    _numObjectsAlreadyFree = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7678
    _numWordsAlreadyFree = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7679
    _last_fc = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7680
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7681
    _sp->initializeIndexedFreeListArrayReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7682
    _sp->dictionary()->initializeDictReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7683
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7684
  assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7685
         "sweep _limit out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7686
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7687
    gclog_or_tty->print("\n====================\nStarting new sweep\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7688
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7689
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7690
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7691
// We need this destructor to reclaim any space at the end
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7692
// of the space, which do_blk below may not have added back to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7693
// the free lists. [basically dealing with the "fringe effect"]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7694
SweepClosure::~SweepClosure() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7695
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7696
  // this should be treated as the end of a free run if any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7697
  // The current free range should be returned to the free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7698
  // as one coalesced chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7699
  if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7700
    flushCurFreeChunk(freeFinger(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7701
      pointer_delta(_limit, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7702
    assert(freeFinger() < _limit, "the finger pointeth off base");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7703
    if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7704
      gclog_or_tty->print("destructor:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7705
      gclog_or_tty->print("Sweep:put_free_blk 0x%x ("SIZE_FORMAT") "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7706
                 "[coalesced:"SIZE_FORMAT"]\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7707
                 freeFinger(), pointer_delta(_limit, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7708
                 lastFreeRangeCoalesced());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7709
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7710
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7711
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7712
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7713
      gclog_or_tty->print("Collected "SIZE_FORMAT" objects, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7714
                          SIZE_FORMAT " bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7715
                 _numObjectsFreed, _numWordsFreed*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7716
      gclog_or_tty->print_cr("\nLive "SIZE_FORMAT" objects,  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7717
                             SIZE_FORMAT" bytes  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7718
        "Already free "SIZE_FORMAT" objects, "SIZE_FORMAT" bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7719
        _numObjectsLive, _numWordsLive*sizeof(HeapWord),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7720
        _numObjectsAlreadyFree, _numWordsAlreadyFree*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7721
      size_t totalBytes = (_numWordsFreed + _numWordsLive + _numWordsAlreadyFree) *
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7722
        sizeof(HeapWord);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7723
      gclog_or_tty->print_cr("Total sweep: "SIZE_FORMAT" bytes", totalBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7724
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7725
      if (PrintCMSStatistics && CMSVerifyReturnedBytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7726
        size_t indexListReturnedBytes = _sp->sumIndexedFreeListArrayReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7727
        size_t dictReturnedBytes = _sp->dictionary()->sumDictReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7728
        size_t returnedBytes = indexListReturnedBytes + dictReturnedBytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7729
        gclog_or_tty->print("Returned "SIZE_FORMAT" bytes", returnedBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7730
        gclog_or_tty->print("   Indexed List Returned "SIZE_FORMAT" bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7731
          indexListReturnedBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7732
        gclog_or_tty->print_cr("        Dictionary Returned "SIZE_FORMAT" bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7733
          dictReturnedBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7734
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7735
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7736
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7737
  // Now, in debug mode, just null out the sweep_limit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7738
  NOT_PRODUCT(_sp->clear_sweep_limit();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7739
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7740
    gclog_or_tty->print("end of sweep\n================\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7741
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7742
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7743
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7744
void SweepClosure::initialize_free_range(HeapWord* freeFinger,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7745
    bool freeRangeInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7746
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7747
    gclog_or_tty->print("---- Start free range 0x%x with free block [%d] (%d)\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7748
               freeFinger, _sp->block_size(freeFinger),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7749
               freeRangeInFreeLists);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7750
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7751
  assert(!inFreeRange(), "Trampling existing free range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7752
  set_inFreeRange(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7753
  set_lastFreeRangeCoalesced(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7754
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7755
  set_freeFinger(freeFinger);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7756
  set_freeRangeInFreeLists(freeRangeInFreeLists);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7757
  if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7758
    if (freeRangeInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7759
      FreeChunk* fc = (FreeChunk*) freeFinger;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7760
      assert(fc->isFree(), "A chunk on the free list should be free.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7761
      assert(fc->size() > 0, "Free range should have a size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7762
      assert(_sp->verifyChunkInFreeLists(fc), "Chunk is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7763
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7764
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7765
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7766
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7767
// Note that the sweeper runs concurrently with mutators. Thus,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7768
// it is possible for direct allocation in this generation to happen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7769
// in the middle of the sweep. Note that the sweeper also coalesces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7770
// contiguous free blocks. Thus, unless the sweeper and the allocator
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7771
// synchronize appropriately freshly allocated blocks may get swept up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7772
// This is accomplished by the sweeper locking the free lists while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7773
// it is sweeping. Thus blocks that are determined to be free are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7774
// indeed free. There is however one additional complication:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7775
// blocks that have been allocated since the final checkpoint and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7776
// mark, will not have been marked and so would be treated as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7777
// unreachable and swept up. To prevent this, the allocator marks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7778
// the bit map when allocating during the sweep phase. This leads,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7779
// however, to a further complication -- objects may have been allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7780
// but not yet initialized -- in the sense that the header isn't yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7781
// installed. The sweeper can not then determine the size of the block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7782
// in order to skip over it. To deal with this case, we use a technique
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7783
// (due to Printezis) to encode such uninitialized block sizes in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7784
// bit map. Since the bit map uses a bit per every HeapWord, but the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7785
// CMS generation has a minimum object size of 3 HeapWords, it follows
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7786
// that "normal marks" won't be adjacent in the bit map (there will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7787
// always be at least two 0 bits between successive 1 bits). We make use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7788
// of these "unused" bits to represent uninitialized blocks -- the bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7789
// corresponding to the start of the uninitialized object and the next
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7790
// bit are both set. Finally, a 1 bit marks the end of the object that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7791
// started with the two consecutive 1 bits to indicate its potentially
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7792
// uninitialized state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7793
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7794
size_t SweepClosure::do_blk_careful(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7795
  FreeChunk* fc = (FreeChunk*)addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7796
  size_t res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7797
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7798
  // check if we are done sweepinrg
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7799
  if (addr == _limit) { // we have swept up to the limit, do nothing more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7800
    assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7801
           "sweep _limit out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7802
    // help the closure application finish
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7803
    return pointer_delta(_sp->end(), _limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7804
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7805
  assert(addr <= _limit, "sweep invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7806
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7807
  // check if we should yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7808
  do_yield_check(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7809
  if (fc->isFree()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7810
    // Chunk that is already free
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7811
    res = fc->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7812
    doAlreadyFreeChunk(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7813
    debug_only(_sp->verifyFreeLists());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7814
    assert(res == fc->size(), "Don't expect the size to change");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7815
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7816
      _numObjectsAlreadyFree++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7817
      _numWordsAlreadyFree += res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7818
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7819
    NOT_PRODUCT(_last_fc = fc;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7820
  } else if (!_bitMap->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7821
    // Chunk is fresh garbage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7822
    res = doGarbageChunk(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7823
    debug_only(_sp->verifyFreeLists());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7824
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7825
      _numObjectsFreed++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7826
      _numWordsFreed += res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7827
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7828
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7829
    // Chunk that is alive.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7830
    res = doLiveChunk(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7831
    debug_only(_sp->verifyFreeLists());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7832
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7833
        _numObjectsLive++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7834
        _numWordsLive += res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7835
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7836
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7837
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7838
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7839
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7840
// For the smart allocation, record following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7841
//  split deaths - a free chunk is removed from its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7842
//      it is being split into two or more chunks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7843
//  split birth - a free chunk is being added to its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7844
//      a larger free chunk has been split and resulted in this free chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7845
//  coal death - a free chunk is being removed from its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7846
//      it is being coalesced into a large free chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7847
//  coal birth - a free chunk is being added to its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7848
//      it was created when two or more free chunks where coalesced into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7849
//      this free chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7850
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7851
// These statistics are used to determine the desired number of free
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7852
// chunks of a given size.  The desired number is chosen to be relative
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7853
// to the end of a CMS sweep.  The desired number at the end of a sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7854
// is the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7855
//      count-at-end-of-previous-sweep (an amount that was enough)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7856
//              - count-at-beginning-of-current-sweep  (the excess)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7857
//              + split-births  (gains in this size during interval)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7858
//              - split-deaths  (demands on this size during interval)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7859
// where the interval is from the end of one sweep to the end of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7860
// next.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7861
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7862
// When sweeping the sweeper maintains an accumulated chunk which is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7863
// the chunk that is made up of chunks that have been coalesced.  That
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7864
// will be termed the left-hand chunk.  A new chunk of garbage that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7865
// is being considered for coalescing will be referred to as the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7866
// right-hand chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7867
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7868
// When making a decision on whether to coalesce a right-hand chunk with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7869
// the current left-hand chunk, the current count vs. the desired count
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7870
// of the left-hand chunk is considered.  Also if the right-hand chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7871
// is near the large chunk at the end of the heap (see
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7872
// ConcurrentMarkSweepGeneration::isNearLargestChunk()), then the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7873
// left-hand chunk is coalesced.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7874
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7875
// When making a decision about whether to split a chunk, the desired count
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7876
// vs. the current count of the candidate to be split is also considered.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7877
// If the candidate is underpopulated (currently fewer chunks than desired)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7878
// a chunk of an overpopulated (currently more chunks than desired) size may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7879
// be chosen.  The "hint" associated with a free list, if non-null, points
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7880
// to a free list which may be overpopulated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7881
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7882
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7883
void SweepClosure::doAlreadyFreeChunk(FreeChunk* fc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7884
  size_t size = fc->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7885
  // Chunks that cannot be coalesced are not in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7886
  // free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7887
  if (CMSTestInFreeList && !fc->cantCoalesce()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7888
    assert(_sp->verifyChunkInFreeLists(fc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7889
      "free chunk should be in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7890
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7891
  // a chunk that is already free, should not have been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7892
  // marked in the bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7893
  HeapWord* addr = (HeapWord*) fc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7894
  assert(!_bitMap->isMarked(addr), "free chunk should be unmarked");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7895
  // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7896
  // addr and purported end of this block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7897
  _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7898
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7899
  // Some chunks cannot be coalesced in under any circumstances.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7900
  // See the definition of cantCoalesce().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7901
  if (!fc->cantCoalesce()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7902
    // This chunk can potentially be coalesced.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7903
    if (_sp->adaptive_freelists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7904
      // All the work is done in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7905
      doPostIsFreeOrGarbageChunk(fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7906
    } else {  // Not adaptive free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7907
      // this is a free chunk that can potentially be coalesced by the sweeper;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7908
      if (!inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7909
        // if the next chunk is a free block that can't be coalesced
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7910
        // it doesn't make sense to remove this chunk from the free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7911
        FreeChunk* nextChunk = (FreeChunk*)(addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7912
        assert((HeapWord*)nextChunk <= _limit, "sweep invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7913
        if ((HeapWord*)nextChunk < _limit  &&    // there's a next chunk...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7914
            nextChunk->isFree()    &&            // which is free...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7915
            nextChunk->cantCoalesce()) {         // ... but cant be coalesced
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7916
          // nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7917
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7918
          // Potentially the start of a new free range:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7919
          // Don't eagerly remove it from the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7920
          // No need to remove it if it will just be put
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7921
          // back again.  (Also from a pragmatic point of view
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7922
          // if it is a free block in a region that is beyond
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7923
          // any allocated blocks, an assertion will fail)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7924
          // Remember the start of a free run.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7925
          initialize_free_range(addr, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7926
          // end - can coalesce with next chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7927
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7928
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7929
        // the midst of a free range, we are coalescing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7930
        debug_only(record_free_block_coalesced(fc);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7931
        if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7932
          gclog_or_tty->print("  -- pick up free block 0x%x (%d)\n", fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7933
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7934
        // remove it from the free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7935
        _sp->removeFreeChunkFromFreeLists(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7936
        set_lastFreeRangeCoalesced(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7937
        // If the chunk is being coalesced and the current free range is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7938
        // in the free lists, remove the current free range so that it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7939
        // will be returned to the free lists in its entirety - all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7940
        // the coalesced pieces included.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7941
        if (freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7942
          FreeChunk* ffc = (FreeChunk*) freeFinger();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7943
          assert(ffc->size() == pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7944
            "Size of free range is inconsistent with chunk size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7945
          if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7946
            assert(_sp->verifyChunkInFreeLists(ffc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7947
              "free range is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7948
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7949
          _sp->removeFreeChunkFromFreeLists(ffc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7950
          set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7951
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7952
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7953
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7954
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7955
    // Code path common to both original and adaptive free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7956
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7957
    // cant coalesce with previous block; this should be treated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7958
    // as the end of a free run if any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7959
    if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7960
      // we kicked some butt; time to pick up the garbage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7961
      assert(freeFinger() < addr, "the finger pointeth off base");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7962
      flushCurFreeChunk(freeFinger(), pointer_delta(addr, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7963
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7964
    // else, nothing to do, just continue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7965
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7966
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7967
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7968
size_t SweepClosure::doGarbageChunk(FreeChunk* fc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7969
  // This is a chunk of garbage.  It is not in any free list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7970
  // Add it to a free list or let it possibly be coalesced into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7971
  // a larger chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7972
  HeapWord* addr = (HeapWord*) fc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7973
  size_t size = CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7974
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7975
  if (_sp->adaptive_freelists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7976
    // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7977
    // addr and purported end of just dead object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7978
    _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7979
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7980
    doPostIsFreeOrGarbageChunk(fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7981
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7982
    if (!inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7983
      // start of a new free range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7984
      assert(size > 0, "A free range should have a size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7985
      initialize_free_range(addr, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7986
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7987
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7988
      // this will be swept up when we hit the end of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7989
      // free range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7990
      if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7991
        gclog_or_tty->print("  -- pick up garbage 0x%x (%d) \n", fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7992
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7993
      // If the chunk is being coalesced and the current free range is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7994
      // in the free lists, remove the current free range so that it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7995
      // will be returned to the free lists in its entirety - all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7996
      // the coalesced pieces included.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7997
      if (freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7998
        FreeChunk* ffc = (FreeChunk*)freeFinger();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7999
        assert(ffc->size() == pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8000
          "Size of free range is inconsistent with chunk size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8001
        if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8002
          assert(_sp->verifyChunkInFreeLists(ffc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8003
            "free range is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8004
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8005
        _sp->removeFreeChunkFromFreeLists(ffc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8006
        set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8007
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8008
      set_lastFreeRangeCoalesced(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8009
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8010
    // this will be swept up when we hit the end of the free range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8011
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8012
    // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8013
    // addr and purported end of just dead object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8014
    _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8015
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8016
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8017
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8018
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8019
size_t SweepClosure::doLiveChunk(FreeChunk* fc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8020
  HeapWord* addr = (HeapWord*) fc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8021
  // The sweeper has just found a live object. Return any accumulated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8022
  // left hand chunk to the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8023
  if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8024
    if (_sp->adaptive_freelists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8025
      flushCurFreeChunk(freeFinger(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8026
                        pointer_delta(addr, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8027
    } else { // not adaptive freelists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8028
      set_inFreeRange(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8029
      // Add the free range back to the free list if it is not already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8030
      // there.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8031
      if (!freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8032
        assert(freeFinger() < addr, "the finger pointeth off base");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8033
        if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8034
          gclog_or_tty->print("Sweep:put_free_blk 0x%x (%d) "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8035
            "[coalesced:%d]\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8036
            freeFinger(), pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8037
            lastFreeRangeCoalesced());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8038
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8039
        _sp->addChunkAndRepairOffsetTable(freeFinger(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8040
          pointer_delta(addr, freeFinger()), lastFreeRangeCoalesced());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8041
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8042
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8043
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8044
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8045
  // Common code path for original and adaptive free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8046
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8047
  // this object is live: we'd normally expect this to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8048
  // an oop, and like to assert the following:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8049
  // assert(oop(addr)->is_oop(), "live block should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8050
  // However, as we commented above, this may be an object whose
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8051
  // header hasn't yet been initialized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8052
  size_t size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8053
  assert(_bitMap->isMarked(addr), "Tautology for this control point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8054
  if (_bitMap->isMarked(addr + 1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8055
    // Determine the size from the bit map, rather than trying to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8056
    // compute it from the object header.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8057
    HeapWord* nextOneAddr = _bitMap->getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8058
    size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8059
    assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8060
           "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8061
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8062
    #ifdef DEBUG
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  8063
      if (oop(addr)->klass_or_null() != NULL &&
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  8064
          (   !_collector->should_unload_classes()
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8065
           || oop(addr)->is_parsable())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8066
        // Ignore mark word because we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8067
        assert(oop(addr)->is_oop(true), "live block should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8068
        assert(size ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8069
               CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8070
               "P-mark and computed size do not agree");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8071
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8072
    #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8073
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8074
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8075
    // This should be an initialized object that's alive.
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  8076
    assert(oop(addr)->klass_or_null() != NULL &&
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  8077
           (!_collector->should_unload_classes()
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8078
            || oop(addr)->is_parsable()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8079
           "Should be an initialized object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8080
    // Ignore mark word because we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8081
    assert(oop(addr)->is_oop(true), "live block should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8082
    // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8083
    // addr and purported end of this block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8084
    size = CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8085
    assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8086
    assert(!_bitMap->isMarked(addr+1), "Tautology for this control point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8087
    DEBUG_ONLY(_bitMap->verifyNoOneBitsInRange(addr+2, addr+size);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8088
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8089
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8090
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8091
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8092
void SweepClosure::doPostIsFreeOrGarbageChunk(FreeChunk* fc,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8093
                                            size_t chunkSize) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8094
  // doPostIsFreeOrGarbageChunk() should only be called in the smart allocation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8095
  // scheme.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8096
  bool fcInFreeLists = fc->isFree();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8097
  assert(_sp->adaptive_freelists(), "Should only be used in this case.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8098
  assert((HeapWord*)fc <= _limit, "sweep invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8099
  if (CMSTestInFreeList && fcInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8100
    assert(_sp->verifyChunkInFreeLists(fc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8101
      "free chunk is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8102
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8103
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8105
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8106
    gclog_or_tty->print_cr("  -- pick up another chunk at 0x%x (%d)", fc, chunkSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8107
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8108
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8109
  HeapWord* addr = (HeapWord*) fc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8110
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8111
  bool coalesce;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8112
  size_t left  = pointer_delta(addr, freeFinger());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8113
  size_t right = chunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8114
  switch (FLSCoalescePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8115
    // numeric value forms a coalition aggressiveness metric
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8116
    case 0:  { // never coalesce
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8117
      coalesce = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8118
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8119
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8120
    case 1: { // coalesce if left & right chunks on overpopulated lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8121
      coalesce = _sp->coalOverPopulated(left) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8122
                 _sp->coalOverPopulated(right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8123
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8124
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8125
    case 2: { // coalesce if left chunk on overpopulated list (default)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8126
      coalesce = _sp->coalOverPopulated(left);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8127
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8128
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8129
    case 3: { // coalesce if left OR right chunk on overpopulated list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8130
      coalesce = _sp->coalOverPopulated(left) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8131
                 _sp->coalOverPopulated(right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8132
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8133
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8134
    case 4: { // always coalesce
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8135
      coalesce = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8136
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8137
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8138
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8139
     ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8140
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8141
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8142
  // Should the current free range be coalesced?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8143
  // If the chunk is in a free range and either we decided to coalesce above
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8144
  // or the chunk is near the large block at the end of the heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8145
  // (isNearLargestChunk() returns true), then coalesce this chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8146
  bool doCoalesce = inFreeRange() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8147
    (coalesce || _g->isNearLargestChunk((HeapWord*)fc));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8148
  if (doCoalesce) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8149
    // Coalesce the current free range on the left with the new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8150
    // chunk on the right.  If either is on a free list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8151
    // it must be removed from the list and stashed in the closure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8152
    if (freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8153
      FreeChunk* ffc = (FreeChunk*)freeFinger();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8154
      assert(ffc->size() == pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8155
        "Size of free range is inconsistent with chunk size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8156
      if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8157
        assert(_sp->verifyChunkInFreeLists(ffc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8158
          "Chunk is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8159
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8160
      _sp->coalDeath(ffc->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8161
      _sp->removeFreeChunkFromFreeLists(ffc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8162
      set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8163
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8164
    if (fcInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8165
      _sp->coalDeath(chunkSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8166
      assert(fc->size() == chunkSize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8167
        "The chunk has the wrong size or is not in the free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8168
      _sp->removeFreeChunkFromFreeLists(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8169
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8170
    set_lastFreeRangeCoalesced(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8171
  } else {  // not in a free range and/or should not coalesce
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8172
    // Return the current free range and start a new one.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8173
    if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8174
      // In a free range but cannot coalesce with the right hand chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8175
      // Put the current free range into the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8176
      flushCurFreeChunk(freeFinger(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8177
        pointer_delta(addr, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8178
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8179
    // Set up for new free range.  Pass along whether the right hand
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8180
    // chunk is in the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8181
    initialize_free_range((HeapWord*)fc, fcInFreeLists);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8182
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8183
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8184
void SweepClosure::flushCurFreeChunk(HeapWord* chunk, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8185
  assert(inFreeRange(), "Should only be called if currently in a free range.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8186
  assert(size > 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8187
    "A zero sized chunk cannot be added to the free lists.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8188
  if (!freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8189
    if(CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8190
      FreeChunk* fc = (FreeChunk*) chunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8191
      fc->setSize(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8192
      assert(!_sp->verifyChunkInFreeLists(fc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8193
        "chunk should not be in free lists yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8194
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8195
    if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8196
      gclog_or_tty->print_cr(" -- add free block 0x%x (%d) to free lists",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8197
                    chunk, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8198
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8199
    // A new free range is going to be starting.  The current
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8200
    // free range has not been added to the free lists yet or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8201
    // was removed so add it back.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8202
    // If the current free range was coalesced, then the death
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8203
    // of the free range was recorded.  Record a birth now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8204
    if (lastFreeRangeCoalesced()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8205
      _sp->coalBirth(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8206
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8207
    _sp->addChunkAndRepairOffsetTable(chunk, size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8208
            lastFreeRangeCoalesced());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8209
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8210
  set_inFreeRange(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8211
  set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8212
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8213
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8214
// We take a break if we've been at this for a while,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8215
// so as to avoid monopolizing the locks involved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8216
void SweepClosure::do_yield_work(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8217
  // Return current free chunk being used for coalescing (if any)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8218
  // to the appropriate freelist.  After yielding, the next
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8219
  // free block encountered will start a coalescing range of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8220
  // free blocks.  If the next free block is adjacent to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8221
  // chunk just flushed, they will need to wait for the next
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8222
  // sweep to be coalesced.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8223
  if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8224
    flushCurFreeChunk(freeFinger(), pointer_delta(addr, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8225
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8226
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8227
  // First give up the locks, then yield, then re-lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8228
  // We should probably use a constructor/destructor idiom to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8229
  // do this unlock/lock or modify the MutexUnlocker class to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8230
  // serve our purpose. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8231
  assert_lock_strong(_bitMap->lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8232
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8233
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8234
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8235
  _bitMap->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8236
  _freelistLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8237
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8238
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8239
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8240
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8241
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8242
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8243
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8244
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8245
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8246
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8247
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8248
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8249
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8250
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8251
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8252
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8253
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8254
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8255
  _freelistLock->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8256
  _bitMap->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8257
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8258
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8259
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8260
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8261
// This is actually very useful in a product build if it can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8262
// be called from the debugger.  Compile it into the product
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8263
// as needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8264
bool debug_verifyChunkInFreeLists(FreeChunk* fc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8265
  return debug_cms_space->verifyChunkInFreeLists(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8266
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8267
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8268
void SweepClosure::record_free_block_coalesced(FreeChunk* fc) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8269
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8270
    gclog_or_tty->print("Sweep:coal_free_blk 0x%x (%d)\n", fc, fc->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8271
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8272
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8273
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8274
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8275
// CMSIsAliveClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8276
bool CMSIsAliveClosure::do_object_b(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8277
  HeapWord* addr = (HeapWord*)obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8278
  return addr != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8279
         (!_span.contains(addr) || _bit_map->isMarked(addr));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8280
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8281
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8282
// CMSKeepAliveClosure: the serial version
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8283
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
  8284
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8285
  if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8286
      !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8287
    _bit_map->mark(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8288
    bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8289
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8290
      if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8291
          _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8292
        // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8293
        simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8294
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8295
    )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8296
    if (simulate_overflow || !_mark_stack->push(obj)) {
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8297
      if (_concurrent_precleaning) {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8298
        // 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
  8299
        // phase deal with it.
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8300
        assert(_collector->overflow_list_is_empty(), "Error");
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8301
        // 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
  8302
        // 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
  8303
        // 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
  8304
        // table.
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8305
        if (obj->is_objArray()) {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8306
          size_t sz = obj->size();
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8307
          HeapWord* end_card_addr =
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8308
            (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
  8309
          MemRegion redirty_range = MemRegion(addr, end_card_addr);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8310
          assert(!redirty_range.is_empty(), "Arithmetical tautology");
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8311
          _collector->_modUnionTable.mark_range(redirty_range);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8312
        } else {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8313
          _collector->_modUnionTable.mark(addr);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8314
        }
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8315
        _collector->_ser_kac_preclean_ovflw++;
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8316
      } else {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8317
        _collector->push_on_overflow_list(obj);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8318
        _collector->_ser_kac_ovflw++;
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8319
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8320
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8321
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8322
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8323
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8324
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
  8325
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
  8326
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8327
// CMSParKeepAliveClosure: a parallel version of the above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8328
// The work queues are private to each closure (thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8329
// 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
  8330
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
  8331
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8332
  if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8333
      !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8334
    // In general, during recursive tracing, several threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8335
    // may be concurrently getting here; the first one to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8336
    // "tag" it, claims it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8337
    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
  8338
      bool res = _work_queue->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8339
      assert(res, "Low water mark should be much less than capacity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8340
      // Do a recursive trim in the hope that this will keep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8341
      // stack usage lower, but leave some oops for potential stealers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8342
      trim_queue(_low_water_mark);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8343
    } // Else, another thread got there first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8344
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8345
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8346
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8347
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
  8348
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
  8349
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8350
void CMSParKeepAliveClosure::trim_queue(uint max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8351
  while (_work_queue->size() > max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8352
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8353
    if (_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8354
      assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8355
      assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8356
             "no white objects on this stack!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8357
      assert(_span.contains((HeapWord*)new_oop), "Out of bounds oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8358
      // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8359
      // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8360
      new_oop->oop_iterate(&_mark_and_push);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8361
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8362
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8363
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8364
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8365
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
  8366
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8367
  if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8368
      !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8369
    if (_bit_map->par_mark(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8370
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8371
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8372
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8373
            _collector->par_simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8374
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8375
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8376
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8377
      )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8378
      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
  8379
        _collector->par_push_on_overflow_list(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8380
        _collector->_par_kac_ovflw++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8381
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8382
    } // Else another thread got there already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8383
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8384
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8385
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8386
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
  8387
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
  8388
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8389
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8390
//  CMSExpansionCause                /////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8391
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8392
const char* CMSExpansionCause::to_string(CMSExpansionCause::Cause cause) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8393
  switch (cause) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8394
    case _no_expansion:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8395
      return "No expansion";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8396
    case _satisfy_free_ratio:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8397
      return "Free ratio";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8398
    case _satisfy_promotion:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8399
      return "Satisfy promotion";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8400
    case _satisfy_allocation:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8401
      return "allocation";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8402
    case _allocate_par_lab:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8403
      return "Par LAB";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8404
    case _allocate_par_spooling_space:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8405
      return "Par Spooling Space";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8406
    case _adaptive_size_policy:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8407
      return "Ergonomics";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8408
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8409
      return "unknown";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8410
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8411
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8412
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8413
void CMSDrainMarkingStackClosure::do_void() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8414
  // the max number to take from overflow list at a time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8415
  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
  8416
  assert(!_concurrent_precleaning || _collector->overflow_list_is_empty(),
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8417
         "Overflow list should be NULL during concurrent phases");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8418
  while (!_mark_stack->isEmpty() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8419
         // if stack is empty, check the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8420
         _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
  8421
    oop obj = _mark_stack->pop();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8422
    HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8423
    assert(_span.contains(addr), "Should be within span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8424
    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
  8425
    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
  8426
    obj->oop_iterate(_keep_alive);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8427
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8428
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8429
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8430
void CMSParDrainMarkingStackClosure::do_void() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8431
  // drain queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8432
  trim_queue(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8433
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8434
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8435
// Trim our work_queue so its length is below max at return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8436
void CMSParDrainMarkingStackClosure::trim_queue(uint max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8437
  while (_work_queue->size() > max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8438
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8439
    if (_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8440
      assert(new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8441
      assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8442
             "no white objects on this stack!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8443
      assert(_span.contains((HeapWord*)new_oop), "Out of bounds oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8444
      // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8445
      // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8446
      new_oop->oop_iterate(&_mark_and_push);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8447
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8448
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8449
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8450
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8451
////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8452
// Support for Marking Stack Overflow list handling and related code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8453
////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8454
// Much of the following code is similar in shape and spirit to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8455
// code used in ParNewGC. We should try and share that code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8456
// as much as possible in the future.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8457
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8458
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8459
// Debugging support for CMSStackOverflowALot
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8460
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8461
// It's OK to call this multi-threaded;  the worst thing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8462
// that can happen is that we'll get a bunch of closely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8463
// spaced simulated oveflows, but that's OK, in fact
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8464
// probably good as it would exercise the overflow code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8465
// under contention.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8466
bool CMSCollector::simulate_overflow() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8467
  if (_overflow_counter-- <= 0) { // just being defensive
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8468
    _overflow_counter = CMSMarkStackOverflowInterval;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8469
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8470
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8471
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8472
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8473
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8474
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8475
bool CMSCollector::par_simulate_overflow() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8476
  return simulate_overflow();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8477
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8478
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8479
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8480
// Single-threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8481
bool CMSCollector::take_from_overflow_list(size_t num, CMSMarkStack* stack) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8482
  assert(stack->isEmpty(), "Expected precondition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8483
  assert(stack->capacity() > num, "Shouldn't bite more than can chew");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8484
  size_t i = num;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8485
  oop  cur = _overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8486
  const markOop proto = markOopDesc::prototype();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8487
  NOT_PRODUCT(size_t n = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8488
  for (oop next; i > 0 && cur != NULL; cur = next, i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8489
    next = oop(cur->mark());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8490
    cur->set_mark(proto);   // until proven otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8491
    assert(cur->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8492
    bool res = stack->push(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8493
    assert(res, "Bit off more than can chew?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8494
    NOT_PRODUCT(n++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8495
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8496
  _overflow_list = cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8497
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8498
  assert(_num_par_pushes >= n, "Too many pops?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8499
  _num_par_pushes -=n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8500
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8501
  return !stack->isEmpty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8502
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8503
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8504
// Multi-threaded; use CAS to break off a prefix
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8505
bool CMSCollector::par_take_from_overflow_list(size_t num,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8506
                                               OopTaskQueue* work_q) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8507
  assert(work_q->size() == 0, "That's the current policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8508
  assert(num < work_q->max_elems(), "Can't bite more than we can chew");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8509
  if (_overflow_list == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8510
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8511
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8512
  // Grab the entire list; we'll put back a suffix
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8513
  oop prefix = (oop)Atomic::xchg_ptr(NULL, &_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8514
  if (prefix == NULL) {  // someone grabbed it before we did ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8515
    // ... we could spin for a short while, but for now we don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8516
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8517
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8518
  size_t i = num;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8519
  oop cur = prefix;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8520
  for (; i > 1 && cur->mark() != NULL; cur = oop(cur->mark()), i--);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8521
  if (cur->mark() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8522
    oop suffix_head = cur->mark(); // suffix will be put back on global list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8523
    cur->set_mark(NULL);           // break off suffix
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8524
    // Find tail of suffix so we can prepend suffix to global list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8525
    for (cur = suffix_head; cur->mark() != NULL; cur = (oop)(cur->mark()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8526
    oop suffix_tail = cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8527
    assert(suffix_tail != NULL && suffix_tail->mark() == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8528
           "Tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8529
    oop observed_overflow_list = _overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8530
    do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8531
      cur = observed_overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8532
      suffix_tail->set_mark(markOop(cur));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8533
      observed_overflow_list =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8534
        (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8535
    } while (cur != observed_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8536
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8537
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8538
  // Push the prefix elements on work_q
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8539
  assert(prefix != NULL, "control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8540
  const markOop proto = markOopDesc::prototype();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8541
  oop next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8542
  NOT_PRODUCT(size_t n = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8543
  for (cur = prefix; cur != NULL; cur = next) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8544
    next = oop(cur->mark());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8545
    cur->set_mark(proto);   // until proven otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8546
    assert(cur->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8547
    bool res = work_q->push(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8548
    assert(res, "Bit off more than we can chew?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8549
    NOT_PRODUCT(n++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8550
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8551
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8552
  assert(_num_par_pushes >= n, "Too many pops?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8553
  Atomic::add_ptr(-(intptr_t)n, &_num_par_pushes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8554
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8555
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8556
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8557
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8558
// Single-threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8559
void CMSCollector::push_on_overflow_list(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8560
  NOT_PRODUCT(_num_par_pushes++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8561
  assert(p->is_oop(), "Not an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8562
  preserve_mark_if_necessary(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8563
  p->set_mark((markOop)_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8564
  _overflow_list = p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8565
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8566
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8567
// Multi-threaded; use CAS to prepend to overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8568
void CMSCollector::par_push_on_overflow_list(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8569
  NOT_PRODUCT(Atomic::inc_ptr(&_num_par_pushes);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8570
  assert(p->is_oop(), "Not an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8571
  par_preserve_mark_if_necessary(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8572
  oop observed_overflow_list = _overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8573
  oop cur_overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8574
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8575
    cur_overflow_list = observed_overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8576
    p->set_mark(markOop(cur_overflow_list));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8577
    observed_overflow_list =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8578
      (oop) Atomic::cmpxchg_ptr(p, &_overflow_list, cur_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8579
  } while (cur_overflow_list != observed_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8580
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8581
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8582
// Single threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8583
// General Note on GrowableArray: pushes may silently fail
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8584
// because we are (temporarily) out of C-heap for expanding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8585
// the stack. The problem is quite ubiquitous and affects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8586
// a lot of code in the JVM. The prudent thing for GrowableArray
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8587
// to do (for now) is to exit with an error. However, that may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8588
// be too draconian in some cases because the caller may be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8589
// able to recover without much harm. For suych cases, we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8590
// should probably introduce a "soft_push" method which returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8591
// an indication of success or failure with the assumption that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8592
// the caller may be able to recover from a failure; code in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8593
// the VM can then be changed, incrementally, to deal with such
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8594
// failures where possible, thus, incrementally hardening the VM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8595
// in such low resource situations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8596
void CMSCollector::preserve_mark_work(oop p, markOop m) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8597
  int PreserveMarkStackSize = 128;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8598
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8599
  if (_preserved_oop_stack == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8600
    assert(_preserved_mark_stack == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8601
           "bijection with preserved_oop_stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8602
    // Allocate the stacks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8603
    _preserved_oop_stack  = new (ResourceObj::C_HEAP)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8604
      GrowableArray<oop>(PreserveMarkStackSize, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8605
    _preserved_mark_stack = new (ResourceObj::C_HEAP)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8606
      GrowableArray<markOop>(PreserveMarkStackSize, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8607
    if (_preserved_oop_stack == NULL || _preserved_mark_stack == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8608
      vm_exit_out_of_memory(2* PreserveMarkStackSize * sizeof(oop) /* punt */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8609
                            "Preserved Mark/Oop Stack for CMS (C-heap)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8610
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8611
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8612
  _preserved_oop_stack->push(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8613
  _preserved_mark_stack->push(m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8614
  assert(m == p->mark(), "Mark word changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8615
  assert(_preserved_oop_stack->length() == _preserved_mark_stack->length(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8616
         "bijection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8617
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8618
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8619
// Single threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8620
void CMSCollector::preserve_mark_if_necessary(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8621
  markOop m = p->mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8622
  if (m->must_be_preserved(p)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8623
    preserve_mark_work(p, m);
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
void CMSCollector::par_preserve_mark_if_necessary(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8628
  markOop m = p->mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8629
  if (m->must_be_preserved(p)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8630
    MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8631
    // Even though we read the mark word without holding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8632
    // the lock, we are assured that it will not change
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8633
    // because we "own" this oop, so no other thread can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8634
    // be trying to push it on the overflow list; see
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8635
    // the assertion in preserve_mark_work() that checks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8636
    // that m == p->mark().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8637
    preserve_mark_work(p, m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8638
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8639
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8640
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8641
// We should be able to do this multi-threaded,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8642
// a chunk of stack being a task (this is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8643
// correct because each oop only ever appears
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8644
// once in the overflow list. However, it's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8645
// not very easy to completely overlap this with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8646
// other operations, so will generally not be done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8647
// until all work's been completed. Because we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8648
// expect the preserved oop stack (set) to be small,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8649
// it's probably fine to do this single-threaded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8650
// We can explore cleverer concurrent/overlapped/parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8651
// processing of preserved marks if we feel the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8652
// need for this in the future. Stack overflow should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8653
// be so rare in practice and, when it happens, its
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8654
// effect on performance so great that this will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8655
// likely just be in the noise anyway.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8656
void CMSCollector::restore_preserved_marks_if_any() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8657
  if (_preserved_oop_stack == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8658
    assert(_preserved_mark_stack == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8659
           "bijection with preserved_oop_stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8660
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8661
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8662
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8663
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8664
         "world should be stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8665
  assert(Thread::current()->is_ConcurrentGC_thread() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8666
         Thread::current()->is_VM_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8667
         "should be single-threaded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8668
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8669
  int length = _preserved_oop_stack->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8670
  assert(_preserved_mark_stack->length() == length, "bijection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8671
  for (int i = 0; i < length; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8672
    oop p = _preserved_oop_stack->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8673
    assert(p->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8674
    assert(_span.contains(p), "oop should be in _span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8675
    assert(p->mark() == markOopDesc::prototype(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8676
           "Set when taken from overflow list");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8677
    markOop m = _preserved_mark_stack->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8678
    p->set_mark(m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8679
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8680
  _preserved_mark_stack->clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8681
  _preserved_oop_stack->clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8682
  assert(_preserved_mark_stack->is_empty() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8683
         _preserved_oop_stack->is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8684
         "stacks were cleared above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8685
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8686
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8687
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8688
bool CMSCollector::no_preserved_marks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8689
  return (   (   _preserved_mark_stack == NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8690
              && _preserved_oop_stack == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8691
          || (   _preserved_mark_stack->is_empty()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8692
              && _preserved_oop_stack->is_empty()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8693
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8694
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8695
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8696
CMSAdaptiveSizePolicy* ASConcurrentMarkSweepGeneration::cms_size_policy() const
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8697
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8698
  GenCollectedHeap* gch = (GenCollectedHeap*) GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8699
  CMSAdaptiveSizePolicy* size_policy =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8700
    (CMSAdaptiveSizePolicy*) gch->gen_policy()->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8701
  assert(size_policy->is_gc_cms_adaptive_size_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8702
    "Wrong type for size policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8703
  return size_policy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8704
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8705
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8706
void ASConcurrentMarkSweepGeneration::resize(size_t cur_promo_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8707
                                           size_t desired_promo_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8708
  if (cur_promo_size < desired_promo_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8709
    size_t expand_bytes = desired_promo_size - cur_promo_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8710
    if (PrintAdaptiveSizePolicy && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8711
      gclog_or_tty->print_cr(" ASConcurrentMarkSweepGeneration::resize "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8712
        "Expanding tenured generation by " SIZE_FORMAT " (bytes)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8713
        expand_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8714
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8715
    expand(expand_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8716
           MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8717
           CMSExpansionCause::_adaptive_size_policy);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8718
  } else if (desired_promo_size < cur_promo_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8719
    size_t shrink_bytes = cur_promo_size - desired_promo_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8720
    if (PrintAdaptiveSizePolicy && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8721
      gclog_or_tty->print_cr(" ASConcurrentMarkSweepGeneration::resize "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8722
        "Shrinking tenured generation by " SIZE_FORMAT " (bytes)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8723
        shrink_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8724
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8725
    shrink(shrink_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8726
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8727
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8728
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8729
CMSGCAdaptivePolicyCounters* ASConcurrentMarkSweepGeneration::gc_adaptive_policy_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8730
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8731
  CMSGCAdaptivePolicyCounters* counters =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8732
    (CMSGCAdaptivePolicyCounters*) gch->collector_policy()->counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8733
  assert(counters->kind() == GCPolicyCounters::CMSGCAdaptivePolicyCountersKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8734
    "Wrong kind of counters");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8735
  return counters;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8736
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8737
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8738
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8739
void ASConcurrentMarkSweepGeneration::update_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8740
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8741
    _space_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8742
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8743
    CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8744
    GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8745
    CMSGCStats* gc_stats_l = (CMSGCStats*) gc_stats();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8746
    assert(gc_stats_l->kind() == GCStats::CMSGCStatsKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8747
      "Wrong gc statistics type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8748
    counters->update_counters(gc_stats_l);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8749
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8750
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8751
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8752
void ASConcurrentMarkSweepGeneration::update_counters(size_t used) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8753
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8754
    _space_counters->update_used(used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8755
    _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8756
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8757
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8758
    CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8759
    GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8760
    CMSGCStats* gc_stats_l = (CMSGCStats*) gc_stats();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8761
    assert(gc_stats_l->kind() == GCStats::CMSGCStatsKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8762
      "Wrong gc statistics type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8763
    counters->update_counters(gc_stats_l);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8764
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8765
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8766
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8767
// The desired expansion delta is computed so that:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8768
// . desired free percentage or greater is used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8769
void ASConcurrentMarkSweepGeneration::compute_new_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8770
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8771
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8772
  GenCollectedHeap* gch = (GenCollectedHeap*) GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8773
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8774
  // If incremental collection failed, we just want to expand
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8775
  // to the limit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8776
  if (incremental_collection_failed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8777
    clear_incremental_collection_failed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8778
    grow_to_reserved();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8779
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8780
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8781
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8782
  assert(UseAdaptiveSizePolicy, "Should be using adaptive sizing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8784
  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8785
    "Wrong type of heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8786
  int prev_level = level() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8787
  assert(prev_level >= 0, "The cms generation is the lowest generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8788
  Generation* prev_gen = gch->get_gen(prev_level);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8789
  assert(prev_gen->kind() == Generation::ASParNew,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8790
    "Wrong type of young generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8791
  ParNewGeneration* younger_gen = (ParNewGeneration*) prev_gen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8792
  size_t cur_eden = younger_gen->eden()->capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8793
  CMSAdaptiveSizePolicy* size_policy = cms_size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8794
  size_t cur_promo = free();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8795
  size_policy->compute_tenured_generation_free_space(cur_promo,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8796
                                                       max_available(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8797
                                                       cur_eden);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8798
  resize(cur_promo, size_policy->promo_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8799
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8800
  // Record the new size of the space in the cms generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8801
  // that is available for promotions.  This is temporary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8802
  // It should be the desired promo size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8803
  size_policy->avg_cms_promo()->sample(free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8804
  size_policy->avg_old_live()->sample(used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8805
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8806
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8807
    CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8808
    counters->update_cms_capacity_counter(capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8809
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8810
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8811
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8812
void ASConcurrentMarkSweepGeneration::shrink_by(size_t desired_bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8813
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8814
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8815
  HeapWord* old_end = _cmsSpace->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8816
  HeapWord* unallocated_start = _cmsSpace->unallocated_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8817
  assert(old_end >= unallocated_start, "Miscalculation of unallocated_start");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8818
  FreeChunk* chunk_at_end = find_chunk_at_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8819
  if (chunk_at_end == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8820
    // No room to shrink
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8821
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8822
      gclog_or_tty->print_cr("No room to shrink: old_end  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8823
        PTR_FORMAT "  unallocated_start  " PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8824
        " chunk_at_end  " PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8825
        old_end, unallocated_start, chunk_at_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8826
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8827
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8828
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8829
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8830
    // Find the chunk at the end of the space and determine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8831
    // how much it can be shrunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8832
    size_t shrinkable_size_in_bytes = chunk_at_end->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8833
    size_t aligned_shrinkable_size_in_bytes =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8834
      align_size_down(shrinkable_size_in_bytes, os::vm_page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8835
    assert(unallocated_start <= chunk_at_end->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8836
      "Inconsistent chunk at end of space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8837
    size_t bytes = MIN2(desired_bytes, aligned_shrinkable_size_in_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8838
    size_t word_size_before = heap_word_size(_virtual_space.committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8839
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8840
    // Shrink the underlying space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8841
    _virtual_space.shrink_by(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8842
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8843
      gclog_or_tty->print_cr("ConcurrentMarkSweepGeneration::shrink_by:"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8844
        " desired_bytes " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8845
        " shrinkable_size_in_bytes " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8846
        " aligned_shrinkable_size_in_bytes " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8847
        "  bytes  " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8848
        desired_bytes, shrinkable_size_in_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8849
        aligned_shrinkable_size_in_bytes, bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8850
      gclog_or_tty->print_cr("          old_end  " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8851
        "  unallocated_start  " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8852
        old_end, unallocated_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8853
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8854
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8855
    // If the space did shrink (shrinking is not guaranteed),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8856
    // shrink the chunk at the end by the appropriate amount.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8857
    if (((HeapWord*)_virtual_space.high()) < old_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8858
      size_t new_word_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8859
        heap_word_size(_virtual_space.committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8860
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8861
      // Have to remove the chunk from the dictionary because it is changing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8862
      // size and might be someplace elsewhere in the dictionary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8863
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8864
      // Get the chunk at end, shrink it, and put it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8865
      // back.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8866
      _cmsSpace->removeChunkFromDictionary(chunk_at_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8867
      size_t word_size_change = word_size_before - new_word_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8868
      size_t chunk_at_end_old_size = chunk_at_end->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8869
      assert(chunk_at_end_old_size >= word_size_change,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8870
        "Shrink is too large");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8871
      chunk_at_end->setSize(chunk_at_end_old_size -
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8872
                          word_size_change);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8873
      _cmsSpace->freed((HeapWord*) chunk_at_end->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8874
        word_size_change);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8875
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8876
      _cmsSpace->returnChunkToDictionary(chunk_at_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8877
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8878
      MemRegion mr(_cmsSpace->bottom(), new_word_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8879
      _bts->resize(new_word_size);  // resize the block offset shared array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8880
      Universe::heap()->barrier_set()->resize_covered_region(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8881
      _cmsSpace->assert_locked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8882
      _cmsSpace->set_end((HeapWord*)_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8883
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8884
      NOT_PRODUCT(_cmsSpace->dictionary()->verify());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8885
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8886
      // update the space and generation capacity counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8887
      if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8888
        _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8889
        _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8890
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8891
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8892
      if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8893
        size_t new_mem_size = _virtual_space.committed_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8894
        size_t old_mem_size = new_mem_size + bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8895
        gclog_or_tty->print_cr("Shrinking %s from %ldK by %ldK to %ldK",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8896
                      name(), old_mem_size/K, bytes/K, new_mem_size/K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8897
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8898
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8899
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8900
    assert(_cmsSpace->unallocated_block() <= _cmsSpace->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8901
      "Inconsistency at end of space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8902
    assert(chunk_at_end->end() == _cmsSpace->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8903
      "Shrinking is inconsistent");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8904
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8905
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8906
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8907
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8908
// Transfer some number of overflown objects to usual marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8909
// stack. Return true if some objects were transferred.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8910
bool MarkRefsIntoAndScanClosure::take_from_overflow_list() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8911
  size_t num = MIN2((size_t)_mark_stack->capacity()/4,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8912
                    (size_t)ParGCDesiredObjsFromOverflowList);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8913
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8914
  bool res = _collector->take_from_overflow_list(num, _mark_stack);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8915
  assert(_collector->overflow_list_is_empty() || res,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8916
         "If list is not empty, we should have taken something");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8917
  assert(!res || !_mark_stack->isEmpty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8918
         "If we took something, it should now be on our stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8919
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8920
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8921
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8922
size_t MarkDeadObjectsClosure::do_blk(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8923
  size_t res = _sp->block_size_no_stall(addr, _collector);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8924
  assert(res != 0, "Should always be able to compute a size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8925
  if (_sp->block_is_obj(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8926
    if (_live_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8927
      // It can't have been dead in a previous cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8928
      guarantee(!_dead_bit_map->isMarked(addr), "No resurrection!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8929
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8930
      _dead_bit_map->mark(addr);      // mark the dead object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8931
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8932
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8933
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8934
}