hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
author ysr
Wed, 23 Dec 2009 09:23:54 -0800
changeset 4574 b2d5b0975515
parent 4455 3f46ab998f18
child 4738 25586a89c1c3
permissions -rw-r--r--
6631166: CMS: better heuristics when combatting fragmentation Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking. Reviewed-by: jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
2105
347008ce7984 6814575: Update copyright year
xdono
parents: 1910
diff changeset
     2
 * Copyright 2001-2009 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
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
void ConcurrentMarkSweepGeneration::ref_processor_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  assert(collector() != NULL, "no collector");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  collector()->ref_processor_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
void CMSCollector::ref_processor_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  if (_ref_processor == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
    // Allocate and initialize a reference processor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
    _ref_processor = ReferenceProcessor::create_ref_processor(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
        _span,                               // span
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
        _cmsGen->refs_discovery_is_atomic(), // atomic_discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
        _cmsGen->refs_discovery_is_mt(),     // mt_discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
        &_is_alive_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
        ParallelGCThreads,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
        ParallelRefProcEnabled);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
    // Initialize the _ref_processor field of CMSGen
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
    _cmsGen->set_ref_processor(_ref_processor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
    // Allocate a dummy ref processor for perm gen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
    ReferenceProcessor* rp2 = new ReferenceProcessor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
    if (rp2 == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
      vm_exit_during_initialization("Could not allocate ReferenceProcessor object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
    _permGen->set_ref_processor(rp2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
CMSAdaptiveSizePolicy* CMSCollector::size_policy() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
    "Wrong type of heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  CMSAdaptiveSizePolicy* sp = (CMSAdaptiveSizePolicy*)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
    gch->gen_policy()->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  assert(sp->is_gc_cms_adaptive_size_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
    "Wrong type of size policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  return sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
CMSGCAdaptivePolicyCounters* CMSCollector::gc_adaptive_policy_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  CMSGCAdaptivePolicyCounters* results =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
    (CMSGCAdaptivePolicyCounters*) collector_policy()->counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  assert(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
    results->kind() == GCPolicyCounters::CMSGCAdaptivePolicyCountersKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    "Wrong gc policy counter kind");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
  return results;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
void ConcurrentMarkSweepGeneration::initialize_performance_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  const char* gen_name = "old";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  // Generation Counters - generation 1, 1 subspace
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
  _gen_counters = new GenerationCounters(gen_name, 1, 1, &_virtual_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  _space_counters = new GSpaceCounters(gen_name, 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
                                       _virtual_space.reserved_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
                                       this, _gen_counters);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
CMSStats::CMSStats(ConcurrentMarkSweepGeneration* cms_gen, unsigned int alpha):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  _cms_gen(cms_gen)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
  assert(alpha <= 100, "bad value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  _saved_alpha = alpha;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
  // Initialize the alphas to the bootstrap value of 100.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
  _gc0_alpha = _cms_alpha = 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
  _cms_begin_time.update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  _cms_end_time.update();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  _gc0_duration = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  _gc0_period = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  _gc0_promoted = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  _cms_duration = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  _cms_period = 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  _cms_allocated = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  _cms_used_at_gc0_begin = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  _cms_used_at_gc0_end = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
  _allow_duty_cycle_reduction = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  _valid_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  _icms_duty_cycle = CMSIncrementalDutyCycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   343
double CMSStats::cms_free_adjustment_factor(size_t free) const {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   344
  // TBD: CR 6909490
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   345
  return 1.0;
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   346
}
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   347
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   348
void CMSStats::adjust_cms_free_adjustment_factor(bool fail, size_t free) {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   349
}
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   350
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
// If promotion failure handling is on use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
// the padded average size of the promotion for each
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
// young generation collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
double CMSStats::time_until_cms_gen_full() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  size_t cms_free = _cms_gen->cmsSpace()->free();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
  size_t expected_promotion = gch->get_gen(0)->capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  if (HandlePromotionFailure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
    expected_promotion = MIN2(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
        (size_t) _cms_gen->gc_stats()->avg_promoted()->padded_average(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
        expected_promotion);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  if (cms_free > expected_promotion) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
    // Start a cms collection if there isn't enough space to promote
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
    // for the next minor collection.  Use the padded average as
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
    // a safety factor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
    cms_free -= expected_promotion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
    // Adjust by the safety factor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
    double cms_free_dbl = (double)cms_free;
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   371
    double cms_adjustment = (100.0 - CMSIncrementalSafetyFactor)/100.0;
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   372
    // Apply a further correction factor which tries to adjust
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   373
    // for recent occurance of concurrent mode failures.
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   374
    cms_adjustment = cms_adjustment * cms_free_adjustment_factor(cms_free);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   375
    cms_free_dbl = cms_free_dbl * cms_adjustment;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
      gclog_or_tty->print_cr("CMSStats::time_until_cms_gen_full: cms_free "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
        SIZE_FORMAT " expected_promotion " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
        cms_free, expected_promotion);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
      gclog_or_tty->print_cr("  cms_free_dbl %f cms_consumption_rate %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
        cms_free_dbl, cms_consumption_rate() + 1.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
    // Add 1 in case the consumption rate goes to zero.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
    return cms_free_dbl / (cms_consumption_rate() + 1.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  return 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
// Compare the duration of the cms collection to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
// time remaining before the cms generation is empty.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
// Note that the time from the start of the cms collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
// to the start of the cms sweep (less than the total
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
// duration of the cms collection) can be used.  This
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
// has been tried and some applications experienced
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
// promotion failures early in execution.  This was
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
// possibly because the averages were not accurate
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
// enough at the beginning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
double CMSStats::time_until_cms_start() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  // We add "gc0_period" to the "work" calculation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  // below because this query is done (mostly) at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  // end of a scavenge, so we need to conservatively
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
  // account for that much possible delay
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  // in the query so as to avoid concurrent mode failures
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
  // due to starting the collection just a wee bit too
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
  // late.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  double work = cms_duration() + gc0_period();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  double deadline = time_until_cms_gen_full();
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   409
  // If a concurrent mode failure occurred recently, we want to be
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   410
  // more conservative and halve our expected time_until_cms_gen_full()
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  if (work > deadline) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
      gclog_or_tty->print(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
        " CMSCollector: collect because of anticipated promotion "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
        "before full %3.7f + %3.7f > %3.7f ", cms_duration(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
        gc0_period(), time_until_cms_gen_full());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
    return 0.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  return work - deadline;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
// Return a duty cycle based on old_duty_cycle and new_duty_cycle, limiting the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
// amount of change to prevent wild oscillation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
unsigned int CMSStats::icms_damped_duty_cycle(unsigned int old_duty_cycle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
                                              unsigned int new_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  assert(old_duty_cycle <= 100, "bad input value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
  assert(new_duty_cycle <= 100, "bad input value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
  // Note:  use subtraction with caution since it may underflow (values are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  // unsigned).  Addition is safe since we're in the range 0-100.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  unsigned int damped_duty_cycle = new_duty_cycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  if (new_duty_cycle < old_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
    const unsigned int largest_delta = MAX2(old_duty_cycle / 4, 5U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
    if (new_duty_cycle + largest_delta < old_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
      damped_duty_cycle = old_duty_cycle - largest_delta;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  } else if (new_duty_cycle > old_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
    const unsigned int largest_delta = MAX2(old_duty_cycle / 4, 15U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
    if (new_duty_cycle > old_duty_cycle + largest_delta) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
      damped_duty_cycle = MIN2(old_duty_cycle + largest_delta, 100U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  assert(damped_duty_cycle <= 100, "invalid duty cycle computed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
  if (CMSTraceIncrementalPacing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
    gclog_or_tty->print(" [icms_damped_duty_cycle(%d,%d) = %d] ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
                           old_duty_cycle, new_duty_cycle, damped_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  return damped_duty_cycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
unsigned int CMSStats::icms_update_duty_cycle_impl() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
  assert(CMSIncrementalPacing && valid(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
         "should be handled in icms_update_duty_cycle()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  double cms_time_so_far = cms_timer().seconds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  double scaled_duration = cms_duration_per_mb() * _cms_used_at_gc0_end / M;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  double scaled_duration_remaining = fabsd(scaled_duration - cms_time_so_far);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  // Avoid division by 0.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
  double time_until_full = MAX2(time_until_cms_gen_full(), 0.01);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  double duty_cycle_dbl = 100.0 * scaled_duration_remaining / time_until_full;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  unsigned int new_duty_cycle = MIN2((unsigned int)duty_cycle_dbl, 100U);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  if (new_duty_cycle > _icms_duty_cycle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
    // Avoid very small duty cycles (1 or 2); 0 is allowed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
    if (new_duty_cycle > 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
      _icms_duty_cycle = icms_damped_duty_cycle(_icms_duty_cycle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
                                                new_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  } else if (_allow_duty_cycle_reduction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
    // The duty cycle is reduced only once per cms cycle (see record_cms_end()).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
    new_duty_cycle = icms_damped_duty_cycle(_icms_duty_cycle, new_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
    // Respect the minimum duty cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
    unsigned int min_duty_cycle = (unsigned int)CMSIncrementalDutyCycleMin;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
    _icms_duty_cycle = MAX2(new_duty_cycle, min_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
  if (PrintGCDetails || CMSTraceIncrementalPacing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
    gclog_or_tty->print(" icms_dc=%d ", _icms_duty_cycle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
  _allow_duty_cycle_reduction = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
  return _icms_duty_cycle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
void CMSStats::print_on(outputStream *st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  st->print(" gc0_alpha=%d,cms_alpha=%d", _gc0_alpha, _cms_alpha);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  st->print(",gc0_dur=%g,gc0_per=%g,gc0_promo=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
               gc0_duration(), gc0_period(), gc0_promoted());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
  st->print(",cms_dur=%g,cms_dur_per_mb=%g,cms_per=%g,cms_alloc=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
            cms_duration(), cms_duration_per_mb(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
            cms_period(), cms_allocated());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
  st->print(",cms_since_beg=%g,cms_since_end=%g",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
            cms_time_since_begin(), cms_time_since_end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
  st->print(",cms_used_beg=" SIZE_FORMAT ",cms_used_end=" SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
            _cms_used_at_gc0_begin, _cms_used_at_gc0_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
  if (CMSIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
    st->print(",dc=%d", icms_duty_cycle());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  if (valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
    st->print(",promo_rate=%g,cms_alloc_rate=%g",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
              promotion_rate(), cms_allocation_rate());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
    st->print(",cms_consumption_rate=%g,time_until_full=%g",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
              cms_consumption_rate(), time_until_cms_gen_full());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  st->print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
#endif // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
CMSCollector::CollectorState CMSCollector::_collectorState =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
                             CMSCollector::Idling;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
bool CMSCollector::_foregroundGCIsActive = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
bool CMSCollector::_foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
                           ConcurrentMarkSweepGeneration* permGen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
                           CardTableRS*                   ct,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
                           ConcurrentMarkSweepPolicy*     cp):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  _cmsGen(cmsGen),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  _permGen(permGen),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  _ct(ct),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  _ref_processor(NULL),    // will be set later
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  _conc_workers(NULL),     // may be set later
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  _abort_preclean(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  _start_sampling(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  _between_prologue_and_epilogue(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  _markBitMap(0, Mutex::leaf + 1, "CMS_markBitMap_lock"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  _perm_gen_verify_bit_map(0, -1 /* no mutex */, "No_lock"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  _modUnionTable((CardTableModRefBS::card_shift - LogHeapWordSize),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
                 -1 /* lock-free */, "No_lock" /* dummy */),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
  _modUnionClosure(&_modUnionTable),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  _modUnionClosurePar(&_modUnionTable),
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   537
  // Adjust my span to cover old (cms) gen and perm gen
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   538
  _span(cmsGen->reserved()._union(permGen->reserved())),
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   539
  // Construct the is_alive_closure with _span & markBitMap
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
   540
  _is_alive_closure(_span, &_markBitMap),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  _restart_addr(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
  _overflow_list(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
  _preserved_oop_stack(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
  _preserved_mark_stack(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
  _stats(cmsGen),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
  _eden_chunk_array(NULL),     // may be set in ctor body
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  _eden_chunk_capacity(0),     // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
  _eden_chunk_index(0),        // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
  _survivor_plab_array(NULL),  // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
  _survivor_chunk_array(NULL), // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
  _survivor_chunk_capacity(0), // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  _survivor_chunk_index(0),    // -- ditto --
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
  _ser_pmc_preclean_ovflw(0),
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
   554
  _ser_kac_preclean_ovflw(0),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  _ser_pmc_remark_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
  _par_pmc_remark_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
  _ser_kac_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
  _par_kac_ovflw(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  _num_par_pushes(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
  _collection_count_start(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
  _verifying(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
  _icms_start_limit(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  _icms_stop_limit(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  _verification_mark_bm(0, Mutex::leaf + 1, "CMS_verification_mark_bm_lock"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  _completed_initialization(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  _collector_policy(cp),
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   569
  _should_unload_classes(false),
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   570
  _concurrent_cycles_since_last_unload(0),
2885
7dd49b9daa4a 6848641: CMSCollector::_roots_scanning_options should be initialized
ysr
parents: 2346
diff changeset
   571
  _roots_scanning_options(0),
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   572
  _inter_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   573
  _intra_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
  if (ExplicitGCInvokesConcurrentAndUnloadsClasses) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
    ExplicitGCInvokesConcurrent = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  // Now expand the span and allocate the collection support structures
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  // (MUT, marking bit map etc.) to cover both generations subject to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  // collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  // First check that _permGen is adjacent to _cmsGen and above it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
  assert(   _cmsGen->reserved().word_size()  > 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
         && _permGen->reserved().word_size() > 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
         "generations should not be of zero size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
  assert(_cmsGen->reserved().intersection(_permGen->reserved()).is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
         "_cmsGen and _permGen should not overlap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
  assert(_cmsGen->reserved().end() == _permGen->reserved().start(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
         "_cmsGen->end() different from _permGen->start()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  // For use by dirty card to oop closures.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
  _cmsGen->cmsSpace()->set_collector(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  _permGen->cmsSpace()->set_collector(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  // Allocate MUT and marking bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
    MutexLockerEx x(_markBitMap.lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
    if (!_markBitMap.allocate(_span)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
      warning("Failed to allocate CMS Bit Map");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
    assert(_markBitMap.covers(_span), "_markBitMap inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
    _modUnionTable.allocate(_span);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
    assert(_modUnionTable.covers(_span), "_modUnionTable inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
  if (!_markStack.allocate(CMSMarkStackSize)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
    warning("Failed to allocate CMS Marking Stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
  if (!_revisitStack.allocate(CMSRevisitStackSize)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
    warning("Failed to allocate CMS Revisit Stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  // Support for multi-threaded concurrent phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
  if (ParallelGCThreads > 0 && CMSConcurrentMTEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
    if (FLAG_IS_DEFAULT(ParallelCMSThreads)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
      // just for now
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
      FLAG_SET_DEFAULT(ParallelCMSThreads, (ParallelGCThreads + 3)/4);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
    if (ParallelCMSThreads > 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
      _conc_workers = new YieldingFlexibleWorkGang("Parallel CMS Threads",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
                                 ParallelCMSThreads, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
      if (_conc_workers == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
        warning("GC/CMS: _conc_workers allocation failure: "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
              "forcing -CMSConcurrentMTEnabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
        CMSConcurrentMTEnabled = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
      CMSConcurrentMTEnabled = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
  if (!CMSConcurrentMTEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
    ParallelCMSThreads = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
    // Turn off CMSCleanOnEnter optimization temporarily for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
    // the MT case where it's not fixed yet; see 6178663.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
    CMSCleanOnEnter = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
  assert((_conc_workers != NULL) == (ParallelCMSThreads > 1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
         "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
  // Parallel task queues; these are shared for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
  // concurrent and stop-world phases of CMS, but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
  // are not shared with parallel scavenge (ParNew).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
    uint i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
    uint num_queues = (uint) MAX2(ParallelGCThreads, ParallelCMSThreads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
    if ((CMSParallelRemarkEnabled || CMSConcurrentMTEnabled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
         || ParallelRefProcEnabled)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
        && num_queues > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
      _task_queues = new OopTaskQueueSet(num_queues);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
      if (_task_queues == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
        warning("task_queues allocation failure.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
      _hash_seed = NEW_C_HEAP_ARRAY(int, num_queues);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
      if (_hash_seed == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
        warning("_hash_seed array allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
      // XXX use a global constant instead of 64!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
      typedef struct OopTaskQueuePadded {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
        OopTaskQueue work_queue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
        char pad[64 - sizeof(OopTaskQueue)];  // prevent false sharing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
      } OopTaskQueuePadded;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
      for (i = 0; i < num_queues; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
        OopTaskQueuePadded *q_padded = new OopTaskQueuePadded();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
        if (q_padded == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
          warning("work_queue allocation failure.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
        _task_queues->register_queue(i, &q_padded->work_queue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
      for (i = 0; i < num_queues; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
        _task_queues->queue(i)->initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
        _hash_seed[i] = 17;  // copied from ParNew
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   688
  _cmsGen ->init_initiating_occupancy(CMSInitiatingOccupancyFraction, CMSTriggerRatio);
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   689
  _permGen->init_initiating_occupancy(CMSInitiatingPermOccupancyFraction, CMSTriggerPermRatio);
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   690
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
  // Clip CMSBootstrapOccupancy between 0 and 100.
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
   692
  _bootstrap_occupancy = ((double)MIN2((uintx)100, MAX2((uintx)0, CMSBootstrapOccupancy)))
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
                         /(double)100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
  _full_gcs_since_conc_gc = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
  // Now tell CMS generations the identity of their collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
  ConcurrentMarkSweepGeneration::set_collector(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
  // Create & start a CMS thread for this CMS collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
  _cmsThread = ConcurrentMarkSweepThread::start(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
  assert(cmsThread() != NULL, "CMS Thread should have been created");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
  assert(cmsThread()->collector() == this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
         "CMS Thread should refer to this gen");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
  assert(CGC_lock != NULL, "Where's the CGC_lock?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
  // Support for parallelizing young gen rescan
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
  _young_gen = gch->prev_gen(_cmsGen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
  if (gch->supports_inline_contig_alloc()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
    _top_addr = gch->top_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
    _end_addr = gch->end_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
    assert(_young_gen != NULL, "no _young_gen");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
    _eden_chunk_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
    _eden_chunk_capacity = (_young_gen->max_capacity()+CMSSamplingGrain)/CMSSamplingGrain;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
    _eden_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, _eden_chunk_capacity);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
    if (_eden_chunk_array == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
      _eden_chunk_capacity = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
      warning("GC/CMS: _eden_chunk_array allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
  assert(_eden_chunk_array != NULL || _eden_chunk_capacity == 0, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
  // Support for parallelizing survivor space rescan
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
  if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
4455
3f46ab998f18 6898857: [Regression] -XX:NewRatio with -XX:+UseConcMarkSweepGC causes fatal error
jmasa
parents: 3913
diff changeset
   726
    size_t max_plab_samples = cp->max_gen0_size()/
3f46ab998f18 6898857: [Regression] -XX:NewRatio with -XX:+UseConcMarkSweepGC causes fatal error
jmasa
parents: 3913
diff changeset
   727
                                ((SurvivorRatio+2)*MinTLABSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
    _survivor_plab_array  = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
    _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
    _cursor               = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
    if (_survivor_plab_array == NULL || _survivor_chunk_array == NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
        || _cursor == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
      warning("Failed to allocate survivor plab/chunk array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
      if (_survivor_plab_array  != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
        FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
        _survivor_plab_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
      if (_survivor_chunk_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
        FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
        _survivor_chunk_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
      if (_cursor != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
        FREE_C_HEAP_ARRAY(size_t, _cursor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
        _cursor = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
      _survivor_chunk_capacity = 2*max_plab_samples;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
      for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
        HeapWord** vec = NEW_C_HEAP_ARRAY(HeapWord*, max_plab_samples);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
        if (vec == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
          warning("Failed to allocate survivor plab array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
          for (int j = i; j > 0; j--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
            FREE_C_HEAP_ARRAY(HeapWord*, _survivor_plab_array[j-1].array());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
          FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
          FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
          _survivor_plab_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
          _survivor_chunk_array = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
          _survivor_chunk_capacity = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
          ChunkArray* cur =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
            ::new (&_survivor_plab_array[i]) ChunkArray(vec,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
                                                        max_plab_samples);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
          assert(cur->end() == 0, "Should be 0");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
          assert(cur->array() == vec, "Should be vec");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
          assert(cur->capacity() == max_plab_samples, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
  assert(   (   _survivor_plab_array  != NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
             && _survivor_chunk_array != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
         || (   _survivor_chunk_capacity == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
             && _survivor_chunk_index == 0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
         "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
  // Choose what strong roots should be scanned depending on verification options
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
  // and perm gen collection mode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
  if (!CMSClassUnloadingEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
    // If class unloading is disabled we want to include all classes into the root set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
    add_root_scanning_option(SharedHeap::SO_AllClasses);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
    add_root_scanning_option(SharedHeap::SO_SystemClasses);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
  NOT_PRODUCT(_overflow_counter = CMSMarkStackOverflowInterval;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
  _gc_counters = new CollectorCounters("CMS", 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
  _completed_initialization = true;
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   790
  _inter_sweep_timer.start();  // start of time
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
const char* ConcurrentMarkSweepGeneration::name() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
  return "concurrent mark-sweep generation";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
void ConcurrentMarkSweepGeneration::update_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
    _space_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
// this is an optimized version of update_counters(). it takes the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
// used value as a parameter rather than computing it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
void ConcurrentMarkSweepGeneration::update_counters(size_t used) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
    _space_counters->update_used(used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
    _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
void ConcurrentMarkSweepGeneration::print() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
  Generation::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
  cmsSpace()->print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
void ConcurrentMarkSweepGeneration::print_statistics() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
  cmsSpace()->printFLCensus(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
void ConcurrentMarkSweepGeneration::printOccupancy(const char *s) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
  if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
    if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
      gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
        level(), short_name(), s, used(), capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
      gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
        level(), short_name(), s, used() / K, capacity() / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
  if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
    gclog_or_tty->print(" "SIZE_FORMAT"("SIZE_FORMAT")",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
              gch->used(), gch->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
    gclog_or_tty->print(" "SIZE_FORMAT"K("SIZE_FORMAT"K)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
              gch->used() / K, gch->capacity() / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
size_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
ConcurrentMarkSweepGeneration::contiguous_available() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
  // dld proposes an improvement in precision here. If the committed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
  // part of the space ends in a free block we should add that to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
  // uncommitted size in the calculation below. Will make this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
  // change later, staying with the approximation below for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
  // time being. -- ysr.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
  return MAX2(_virtual_space.uncommitted_size(), unsafe_max_alloc_nogc());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
size_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
ConcurrentMarkSweepGeneration::unsafe_max_alloc_nogc() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
  return _cmsSpace->max_alloc_in_words() * HeapWordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
size_t ConcurrentMarkSweepGeneration::max_available() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
  return free() + _virtual_space.uncommitted_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
bool ConcurrentMarkSweepGeneration::promotion_attempt_is_safe(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
    size_t max_promotion_in_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
    bool younger_handles_promotion_failure) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
  // This is the most conservative test.  Full promotion is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
  // guaranteed if this is used. The multiplicative factor is to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
  // account for the worst case "dilatation".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
  double adjusted_max_promo_bytes = _dilatation_factor * max_promotion_in_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
  if (adjusted_max_promo_bytes > (double)max_uintx) { // larger than size_t
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
    adjusted_max_promo_bytes = (double)max_uintx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
  bool result = (max_contiguous_available() >= (size_t)adjusted_max_promo_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
  if (younger_handles_promotion_failure && !result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
    // Full promotion is not guaranteed because fragmentation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
    // of the cms generation can prevent the full promotion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
    result = (max_available() >= (size_t)adjusted_max_promo_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
    if (!result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
      // With promotion failure handling the test for the ability
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
      // to support the promotion does not have to be guaranteed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
      // Use an average of the amount promoted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
      result = max_available() >= (size_t)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
        gc_stats()->avg_promoted()->padded_average();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
      if (PrintGC && Verbose && result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
        gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
          "\nConcurrentMarkSweepGeneration::promotion_attempt_is_safe"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
          " max_available: " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
          " avg_promoted: " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
          max_available(), (size_t)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
          gc_stats()->avg_promoted()->padded_average());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
      if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
        gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
          "\nConcurrentMarkSweepGeneration::promotion_attempt_is_safe"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
          " max_available: " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
          " adj_max_promo_bytes: " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
          max_available(), (size_t)adjusted_max_promo_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
    if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
      gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
        "\nConcurrentMarkSweepGeneration::promotion_attempt_is_safe"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
        " contiguous_available: " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
        " adj_max_promo_bytes: " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
        max_contiguous_available(), (size_t)adjusted_max_promo_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   917
// At a promotion failure dump information on block layout in heap
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   918
// (cms old generation).
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   919
void ConcurrentMarkSweepGeneration::promotion_failure_occurred() {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   920
  if (CMSDumpAtPromotionFailure) {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   921
    cmsSpace()->dump_at_safepoint_with_locks(collector(), gclog_or_tty);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   922
  }
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   923
}
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
   924
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
CompactibleSpace*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
ConcurrentMarkSweepGeneration::first_compaction_space() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
  return _cmsSpace;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
void ConcurrentMarkSweepGeneration::reset_after_compaction() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
  // Clear the promotion information.  These pointers can be adjusted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
  // along with all the other pointers into the heap but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
  // compaction is expected to be a rare event with
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
  // a heap using cms so don't do it without seeing the need.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
  if (ParallelGCThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
    for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
      _par_gc_thread_states[i]->promo.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
void ConcurrentMarkSweepGeneration::space_iterate(SpaceClosure* blk, bool usedOnly) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
  blk->do_space(_cmsSpace);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
void ConcurrentMarkSweepGeneration::compute_new_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
  // If incremental collection failed, we just want to expand
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
  // to the limit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
  if (incremental_collection_failed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
    clear_incremental_collection_failed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
    grow_to_reserved();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
  size_t expand_bytes = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
  double free_percentage = ((double) free()) / capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
  double desired_free_percentage = (double) MinHeapFreeRatio / 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
  double maximum_free_percentage = (double) MaxHeapFreeRatio / 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
  // compute expansion delta needed for reaching desired free percentage
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
  if (free_percentage < desired_free_percentage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
    size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
    assert(desired_capacity >= capacity(), "invalid expansion size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
    expand_bytes = MAX2(desired_capacity - capacity(), MinHeapDeltaBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
  if (expand_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
      size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
      gclog_or_tty->print_cr("\nFrom compute_new_size: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
      gclog_or_tty->print_cr("  Free fraction %f", free_percentage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
      gclog_or_tty->print_cr("  Desired free fraction %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
        desired_free_percentage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
      gclog_or_tty->print_cr("  Maximum free fraction %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
        maximum_free_percentage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
      gclog_or_tty->print_cr("  Capactiy "SIZE_FORMAT, capacity()/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
      gclog_or_tty->print_cr("  Desired capacity "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
        desired_capacity/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
      int prev_level = level() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
      if (prev_level >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
        size_t prev_size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
        GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
        Generation* prev_gen = gch->_gens[prev_level];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
        prev_size = prev_gen->capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
          gclog_or_tty->print_cr("  Younger gen size "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
                                 prev_size/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
      gclog_or_tty->print_cr("  unsafe_max_alloc_nogc "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
        unsafe_max_alloc_nogc()/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
      gclog_or_tty->print_cr("  contiguous available "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
        contiguous_available()/1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
      gclog_or_tty->print_cr("  Expand by "SIZE_FORMAT" (bytes)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
        expand_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
    // safe if expansion fails
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
    expand(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
      gclog_or_tty->print_cr("  Expanded free fraction %f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
        ((double) free()) / capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
Mutex* ConcurrentMarkSweepGeneration::freelistLock() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
  return cmsSpace()->freelistLock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
HeapWord* ConcurrentMarkSweepGeneration::allocate(size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
                                                  bool   tlab) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
  CMSSynchronousYieldRequest yr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
  MutexLockerEx x(freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
                  Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
  return have_lock_and_allocate(size, tlab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
HeapWord* ConcurrentMarkSweepGeneration::have_lock_and_allocate(size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
                                                  bool   tlab) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
  size_t adjustedSize = CompactibleFreeListSpace::adjustObjectSize(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
  HeapWord* res = cmsSpace()->allocate(adjustedSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
  // Allocate the object live (grey) if the background collector has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
  // started marking. This is necessary because the marker may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
  // have passed this address and consequently this object will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
  // not otherwise be greyed and would be incorrectly swept up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
  // Note that if this object contains references, the writing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
  // of those references will dirty the card containing this object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
  // allowing the object to be blackened (and its references scanned)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
  // either during a preclean phase or at the final checkpoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
  if (res != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
    collector()->direct_allocated(res, adjustedSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
    _direct_allocated_words += adjustedSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
    // allocation counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
      _numObjectsAllocated++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
      _numWordsAllocated += (int)adjustedSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
// In the case of direct allocation by mutators in a generation that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
// is being concurrently collected, the object must be allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
// live (grey) if the background collector has started marking.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
// This is necessary because the marker may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
// have passed this address and consequently this object will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
// not otherwise be greyed and would be incorrectly swept up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
// Note that if this object contains references, the writing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
// of those references will dirty the card containing this object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
// allowing the object to be blackened (and its references scanned)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
// either during a preclean phase or at the final checkpoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
void CMSCollector::direct_allocated(HeapWord* start, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
  assert(_markBitMap.covers(start, size), "Out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
  if (_collectorState >= Marking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
    MutexLockerEx y(_markBitMap.lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
                    Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
    // [see comments preceding SweepClosure::do_blk() below for details]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
    // 1. need to mark the object as live so it isn't collected
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
    // 2. need to mark the 2nd bit to indicate the object may be uninitialized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
    // 3. need to mark the end of the object so sweeper can skip over it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
    //    if it's uninitialized when the sweeper reaches it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
    _markBitMap.mark(start);          // object is live
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
    _markBitMap.mark(start + 1);      // object is potentially uninitialized?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
    _markBitMap.mark(start + size - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
                                      // mark end of object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
  // check that oop looks uninitialized
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1068
  assert(oop(start)->klass_or_null() == NULL, "_klass should be NULL");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
void CMSCollector::promoted(bool par, HeapWord* start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
                            bool is_obj_array, size_t obj_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
  assert(_markBitMap.covers(start), "Out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
  // See comment in direct_allocated() about when objects should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
  // be allocated live.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
  if (_collectorState >= Marking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
    // we already hold the marking bit map lock, taken in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
    // the prologue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
    if (par) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
      _markBitMap.par_mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
      _markBitMap.mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
    // We don't need to mark the object as uninitialized (as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
    // in direct_allocated above) because this is being done with the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
    // world stopped and the object will be initialized by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
    // time the sweeper gets to look at it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
    assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
           "expect promotion only at safepoints");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
    if (_collectorState < Sweeping) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
      // Mark the appropriate cards in the modUnionTable, so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
      // this object gets scanned before the sweep. If this is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
      // not done, CMS generation references in the object might
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
      // not get marked.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
      // For the case of arrays, which are otherwise precisely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
      // marked, we need to dirty the entire array, not just its head.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
      if (is_obj_array) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
        // The [par_]mark_range() method expects mr.end() below to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
        // be aligned to the granularity of a bit's representation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
        // in the heap. In the case of the MUT below, that's a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
        // card size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
        MemRegion mr(start,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
                     (HeapWord*)round_to((intptr_t)(start + obj_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
                        CardTableModRefBS::card_size /* bytes */));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
        if (par) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
          _modUnionTable.par_mark_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
          _modUnionTable.mark_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
      } else {  // not an obj array; we can just mark the head
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
        if (par) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
          _modUnionTable.par_mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
          _modUnionTable.mark(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
static inline size_t percent_of_space(Space* space, HeapWord* addr)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
  size_t delta = pointer_delta(addr, space->bottom());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
  return (size_t)(delta * 100.0 / (space->capacity() / HeapWordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
void CMSCollector::icms_update_allocation_limits()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
  Generation* gen0 = GenCollectedHeap::heap()->get_gen(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
  EdenSpace* eden = gen0->as_DefNewGeneration()->eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
  const unsigned int duty_cycle = stats().icms_update_duty_cycle();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
  if (CMSTraceIncrementalPacing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
    stats().print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
  assert(duty_cycle <= 100, "invalid duty cycle");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
  if (duty_cycle != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
    // The duty_cycle is a percentage between 0 and 100; convert to words and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
    // then compute the offset from the endpoints of the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
    size_t free_words = eden->free() / HeapWordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
    double free_words_dbl = (double)free_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
    size_t duty_cycle_words = (size_t)(free_words_dbl * duty_cycle / 100.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
    size_t offset_words = (free_words - duty_cycle_words) / 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
    _icms_start_limit = eden->top() + offset_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
    _icms_stop_limit = eden->end() - offset_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
    // The limits may be adjusted (shifted to the right) by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
    // CMSIncrementalOffset, to allow the application more mutator time after a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
    // young gen gc (when all mutators were stopped) and before CMS starts and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
    // takes away one or more cpus.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
    if (CMSIncrementalOffset != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
      double adjustment_dbl = free_words_dbl * CMSIncrementalOffset / 100.0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
      size_t adjustment = (size_t)adjustment_dbl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
      HeapWord* tmp_stop = _icms_stop_limit + adjustment;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
      if (tmp_stop > _icms_stop_limit && tmp_stop < eden->end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
        _icms_start_limit += adjustment;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
        _icms_stop_limit = tmp_stop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
  if (duty_cycle == 0 || (_icms_start_limit == _icms_stop_limit)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
    _icms_start_limit = _icms_stop_limit = eden->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
  // Install the new start limit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
  eden->set_soft_end(_icms_start_limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
  if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
    gclog_or_tty->print(" icms alloc limits:  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
                           PTR_FORMAT "," PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
                           " (" SIZE_FORMAT "%%," SIZE_FORMAT "%%) ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
                           _icms_start_limit, _icms_stop_limit,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
                           percent_of_space(eden, _icms_start_limit),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
                           percent_of_space(eden, _icms_stop_limit));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
    if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
      gclog_or_tty->print("eden:  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
      eden->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
// Any changes here should try to maintain the invariant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
// that if this method is called with _icms_start_limit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
// and _icms_stop_limit both NULL, then it should return NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
// and not notify the icms thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
CMSCollector::allocation_limit_reached(Space* space, HeapWord* top,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
                                       size_t word_size)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
  // A start_limit equal to end() means the duty cycle is 0, so treat that as a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
  // nop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
  if (CMSIncrementalMode && _icms_start_limit != space->end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
    if (top <= _icms_start_limit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
      if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
        space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
        gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
        gclog_or_tty->print_cr(" start limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
                               ", new limit=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
                               " (" SIZE_FORMAT "%%)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
                               top, _icms_stop_limit,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
                               percent_of_space(space, _icms_stop_limit));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
      ConcurrentMarkSweepThread::start_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
      assert(top < _icms_stop_limit, "Tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
      if (word_size < pointer_delta(_icms_stop_limit, top)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
        return _icms_stop_limit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
      // The allocation will cross both the _start and _stop limits, so do the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
      // stop notification also and return end().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
      if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
        space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
        gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
        gclog_or_tty->print_cr(" +stop limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
                               ", new limit=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
                               " (" SIZE_FORMAT "%%)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
                               top, space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
                               percent_of_space(space, space->end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
      ConcurrentMarkSweepThread::stop_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
      return space->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
    if (top <= _icms_stop_limit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
      if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
        space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
        gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
        gclog_or_tty->print_cr(" stop limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
                               ", new limit=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
                               " (" SIZE_FORMAT "%%)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
                               top, space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
                               percent_of_space(space, space->end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
      ConcurrentMarkSweepThread::stop_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
      return space->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1241
    if (CMSTraceIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
      space->print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
      gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
      gclog_or_tty->print_cr(" end limit top=" PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
                             ", new limit=" PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
                             top, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  1253
oop ConcurrentMarkSweepGeneration::promote(oop obj, size_t obj_size) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
  assert(obj_size == (size_t)obj->size(), "bad obj_size passed in");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
  // allocate, copy and if necessary update promoinfo --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
  // delegate to underlying space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
  if (Universe::heap()->promotion_should_fail()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
#endif  // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  1265
  oop res = _cmsSpace->promote(obj, obj_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
  if (res == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
    // expand and retry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
    size_t s = _cmsSpace->expansionSpaceRequired(obj_size);  // HeapWords
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
    expand(s*HeapWordSize, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
      CMSExpansionCause::_satisfy_promotion);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
    // Since there's currently no next generation, we don't try to promote
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
    // into a more senior generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
    assert(next_gen() == NULL, "assumption, based upon which no attempt "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
                               "is made to pass on a possibly failing "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
                               "promotion to next generation");
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  1276
    res = _cmsSpace->promote(obj, obj_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
  if (res != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
    // See comment in allocate() about when objects should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
    // be allocated live.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
    assert(obj->is_oop(), "Will dereference klass pointer below");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
    collector()->promoted(false,           // Not parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
                          (HeapWord*)res, obj->is_objArray(), obj_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
    // promotion counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
      _numObjectsPromoted++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
      _numWordsPromoted +=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
        (int)(CompactibleFreeListSpace::adjustObjectSize(obj->size()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
ConcurrentMarkSweepGeneration::allocation_limit_reached(Space* space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
                                             HeapWord* top,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
                                             size_t word_sz)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
  return collector()->allocation_limit_reached(space, top, word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
// Things to support parallel young-gen collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
ConcurrentMarkSweepGeneration::par_promote(int thread_num,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
                                           oop old, markOop m,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
                                           size_t word_sz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
  if (Universe::heap()->promotion_should_fail()) {
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
#endif  // #ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
  CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
  PromotionInfo* promoInfo = &ps->promo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
  // if we are tracking promotions, then first ensure space for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
  // promotion (including spooling space for saving header if necessary).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
  // then allocate and copy, then track promoted info if needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
  // When tracking (see PromotionInfo::track()), the mark word may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
  // be displaced and in this case restoration of the mark word
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
  // occurs in the (oop_since_save_marks_)iterate phase.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
  if (promoInfo->tracking() && !promoInfo->ensure_spooling_space()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
    // Out of space for allocating spooling buffers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
    // try expanding and allocating spooling buffers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
    if (!expand_and_ensure_spooling_space(promoInfo)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
  assert(promoInfo->has_spooling_space(), "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
  HeapWord* obj_ptr = ps->lab.alloc(word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
  if (obj_ptr == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
     obj_ptr = expand_and_par_lab_allocate(ps, word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
     if (obj_ptr == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
       return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
  oop obj = oop(obj_ptr);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1338
  assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
  // Otherwise, copy the object.  Here we must be careful to insert the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
  // 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
  1341
  // Except with compressed oops it's the mark word.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
  HeapWord* old_ptr = (HeapWord*)old;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
  if (word_sz > (size_t)oopDesc::header_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
    Copy::aligned_disjoint_words(old_ptr + oopDesc::header_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
                                 obj_ptr + oopDesc::header_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
                                 word_sz - oopDesc::header_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
  }
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1348
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1349
  if (UseCompressedOops) {
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1350
    // Copy gap missed by (aligned) header size calculation above
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1351
    obj->set_klass_gap(old->klass_gap());
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1352
  }
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1353
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
  // Restore the mark word copied above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1355
  obj->set_mark(m);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1356
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
  // Now we can track the promoted object, if necessary.  We take care
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
  // To delay the transition from uninitialized to full object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
  // (i.e., insertion of klass pointer) until after, so that it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1360
  // atomically becomes a promoted object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1361
  if (promoInfo->tracking()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1362
    promoInfo->track((PromotedObject*)obj, old->klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
  }
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1364
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  1365
  // Finally, install the klass pointer (this should be volatile).
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
  obj->set_klass(old->klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
  assert(old->is_oop(), "Will dereference klass ptr below");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
  collector()->promoted(true,          // parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
                        obj_ptr, old->is_objArray(), word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
    Atomic::inc(&_numObjectsPromoted);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
    Atomic::add((jint)CompactibleFreeListSpace::adjustObjectSize(obj->size()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
                &_numWordsPromoted);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
  return obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
ConcurrentMarkSweepGeneration::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
par_promote_alloc_undo(int thread_num,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
                       HeapWord* obj, size_t word_sz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
  // CMS does not support promotion undo.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
  ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
ConcurrentMarkSweepGeneration::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
par_promote_alloc_done(int thread_num) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
  CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  1393
  ps->lab.retire(thread_num);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
ConcurrentMarkSweepGeneration::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
par_oop_since_save_marks_iterate_done(int thread_num) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
  CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
  ParScanWithoutBarrierClosure* dummy_cl = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
  ps->promo.promoted_oops_iterate_nv(dummy_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1403
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
// XXXPERM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
bool ConcurrentMarkSweepGeneration::should_collect(bool   full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
                                                   size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
                                                   bool   tlab)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
  // We allow a STW collection only if a full
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
  // collection was requested.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
  return full || should_allocate(size, tlab); // FIX ME !!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
  // This and promotion failure handling are connected at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
  // hip and should be fixed by untying them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
bool CMSCollector::shouldConcurrentCollect() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
  if (_full_gc_requested) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
    assert(ExplicitGCInvokesConcurrent, "Unexpected state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
      gclog_or_tty->print_cr("CMSCollector: collect because of explicit "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
                             " gc request");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
  // For debugging purposes, change the type of collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
  // If the rotation is not on the concurrent collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
  // type, don't start a concurrent collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
    if (RotateCMSCollectionTypes &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
        (_cmsGen->debug_collection_type() !=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
          ConcurrentMarkSweepGeneration::Concurrent_collection_type)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
      assert(_cmsGen->debug_collection_type() !=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
        ConcurrentMarkSweepGeneration::Unknown_collection_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
        "Bad cms collection type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
  FreelistLocker x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
  // ------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
  // Print out lots of information which affects the initiation of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
  // a collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
  if (PrintCMSInitiationStatistics && stats().valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
    gclog_or_tty->print("CMSCollector shouldConcurrentCollect: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
    gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
    gclog_or_tty->print_cr("");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
    stats().print_on(gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
    gclog_or_tty->print_cr("time_until_cms_gen_full %3.7f",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
      stats().time_until_cms_gen_full());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
    gclog_or_tty->print_cr("free="SIZE_FORMAT, _cmsGen->free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
    gclog_or_tty->print_cr("contiguous_available="SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
                           _cmsGen->contiguous_available());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
    gclog_or_tty->print_cr("promotion_rate=%g", stats().promotion_rate());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
    gclog_or_tty->print_cr("cms_allocation_rate=%g", stats().cms_allocation_rate());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
    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
  1457
    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
  1458
    gclog_or_tty->print_cr("initiatingPermOccupancy=%3.7f", _permGen->initiating_occupancy());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
  // ------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
  // If the estimated time to complete a cms collection (cms_duration())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
  // is less than the estimated time remaining until the cms generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
  // is full, start a collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
  if (!UseCMSInitiatingOccupancyOnly) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
    if (stats().valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
      if (stats().time_until_cms_start() == 0.0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
        return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
      // We want to conservatively collect somewhat early in order
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
      // to try and "bootstrap" our CMS/promotion statistics;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
      // this branch will not fire after the first successful CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
      // collection because the stats should then be valid.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
      if (_cmsGen->occupancy() >= _bootstrap_occupancy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
        if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
          gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
            " CMSCollector: collect for bootstrapping statistics:"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
            " occupancy = %f, boot occupancy = %f", _cmsGen->occupancy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
            _bootstrap_occupancy);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
        return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
  // Otherwise, we start a collection cycle if either the perm gen or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
  // old gen want a collection cycle started. Each may use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
  // an appropriate criterion for making this decision.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
  // 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
  1491
  // 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
  1492
  if (_cmsGen->should_concurrent_collect()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
      gclog_or_tty->print_cr("CMS old gen initiated");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1499
  // 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
  1500
  // 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
  1501
  // late anyway.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1502
  GenCollectedHeap* gch = GenCollectedHeap::heap();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1503
  assert(gch->collector_policy()->is_two_generation_policy(),
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1504
         "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
  1505
  if (gch->incremental_collection_will_fail()) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1506
    if (PrintGCDetails && Verbose) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1507
      gclog_or_tty->print("CMSCollector: collect because incremental collection will fail ");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1512
  if (CMSClassUnloadingEnabled && _permGen->should_concurrent_collect()) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1513
    bool res = update_should_unload_classes();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1514
    if (res) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1515
      if (Verbose && PrintGCDetails) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1516
        gclog_or_tty->print_cr("CMS perm gen initiated");
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1517
      }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1518
      return true;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1519
    }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1520
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1521
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1522
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1523
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1524
// Clear _expansion_cause fields of constituent generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1525
void CMSCollector::clear_expansion_cause() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
  _cmsGen->clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
  _permGen->clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1530
// 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
  1531
// 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
  1532
// 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
  1533
// 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
  1534
// 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
  1535
// UseCMSInitiatingOccupancyOnly.  This also has the advantage of
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1536
// 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
  1537
// collections.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1538
// 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
  1539
// conditions hold:
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1540
// . our current occupancy exceeds the configured initiating occupancy
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1541
//   for this generation, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1542
// . 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
  1543
//   expansion, done a collection of this generation, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1544
// . 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
  1545
//   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
  1546
//   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
  1547
//   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
  1548
//   the generation, etc... or ...
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1549
// [.(currently done by CMSCollector::shouldConcurrentCollect() only for
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1550
//   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
  1551
//   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
  1552
//   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
  1553
bool ConcurrentMarkSweepGeneration::should_concurrent_collect() const {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1554
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
  assert_lock_strong(freelistLock());
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1556
  if (occupancy() > initiating_occupancy()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
      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
  1559
        short_name(), occupancy(), initiating_occupancy());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
  if (UseCMSInitiatingOccupancyOnly) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
  if (expansion_cause() == CMSExpansionCause::_satisfy_allocation) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
      gclog_or_tty->print(" %s: collect because expanded for allocation ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
        short_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
  }
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1573
  if (_cmsSpace->should_concurrent_collect()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
    if (PrintGCDetails && Verbose) {
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  1575
      gclog_or_tty->print(" %s: collect because cmsSpace says so ",
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1576
        short_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1578
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1579
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1580
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1581
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1582
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
void ConcurrentMarkSweepGeneration::collect(bool   full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1584
                                            bool   clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1585
                                            size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1586
                                            bool   tlab)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1587
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1588
  collector()->collect(full, clear_all_soft_refs, size, tlab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1589
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1590
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1591
void CMSCollector::collect(bool   full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1592
                           bool   clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1593
                           size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
                           bool   tlab)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
  if (!UseCMSCollectionPassing && _collectorState > Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
    // For debugging purposes skip the collection if the state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
    // is not currently idle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
      gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " skipped full:%d CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
        Thread::current(), full, _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1606
  // The following "if" branch is present for defensive reasons.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
  // In the current uses of this interface, it can be replaced with:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
  // assert(!GC_locker.is_active(), "Can't be called otherwise");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
  // But I am not placing that assert here to allow future
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
  // generality in invoking this interface.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
  if (GC_locker::is_active()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
    // A consistency test for GC_locker
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
    assert(GC_locker::needs_gc(), "Should have been set already");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
    // Skip this foreground collection, instead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
    // expanding the heap if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
    // Need the free list locks for the call to free() in compute_new_size()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
    compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1618
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1620
  acquire_control_and_collect(full, clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1621
  _full_gcs_since_conc_gc++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1622
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1624
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1625
void CMSCollector::request_full_gc(unsigned int full_gc_count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1626
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
  unsigned int gc_count = gch->total_full_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
  if (gc_count == full_gc_count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
    MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
    _full_gc_requested = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
    CGC_lock->notify();   // nudge CMS thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
// The foreground and background collectors need to coordinate in order
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1637
// to make sure that they do not mutually interfere with CMS collections.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1638
// When a background collection is active,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
// the foreground collector may need to take over (preempt) and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
// synchronously complete an ongoing collection. Depending on the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
// frequency of the background collections and the heap usage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
// of the application, this preemption can be seldom or frequent.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
// There are only certain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1644
// points in the background collection that the "collection-baton"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1645
// can be passed to the foreground collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1647
// The foreground collector will wait for the baton before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
// starting any part of the collection.  The foreground collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
// will only wait at one location.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1650
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1651
// The background collector will yield the baton before starting a new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1652
// phase of the collection (e.g., before initial marking, marking from roots,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1653
// precleaning, final re-mark, sweep etc.)  This is normally done at the head
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1654
// of the loop which switches the phases. The background collector does some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1655
// of the phases (initial mark, final re-mark) with the world stopped.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1656
// Because of locking involved in stopping the world,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
// the foreground collector should not block waiting for the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1658
// collector when it is doing a stop-the-world phase.  The background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
// collector will yield the baton at an additional point just before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
// it enters a stop-the-world phase.  Once the world is stopped, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1661
// background collector checks the phase of the collection.  If the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
// phase has not changed, it proceeds with the collection.  If the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
// phase has changed, it skips that phase of the collection.  See
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
// the comments on the use of the Heap_lock in collect_in_background().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
// Variable used in baton passing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
//   _foregroundGCIsActive - Set to true by the foreground collector when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
//      it wants the baton.  The foreground clears it when it has finished
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1669
//      the collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
//   _foregroundGCShouldWait - Set to true by the background collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
//        when it is running.  The foreground collector waits while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
//      _foregroundGCShouldWait is true.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
//  CGC_lock - monitor used to protect access to the above variables
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
//      and to notify the foreground and background collectors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
//  _collectorState - current state of the CMS collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
// The foreground collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
//   acquires the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
//   sets _foregroundGCIsActive
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
//   waits on the CGC_lock for _foregroundGCShouldWait to be false
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
//     various locks acquired in preparation for the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
//     are released so as not to block the background collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
//     that is in the midst of a collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
//   proceeds with the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
//   clears _foregroundGCIsActive
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
//   returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
// The background collector in a loop iterating on the phases of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
//      collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
//   acquires the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
//   sets _foregroundGCShouldWait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
//   if _foregroundGCIsActive is set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
//     clears _foregroundGCShouldWait, notifies _CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
//     waits on _CGC_lock for _foregroundGCIsActive to become false
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
//     and exits the loop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
//   otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
//     proceed with that phase of the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
//     if the phase is a stop-the-world phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
//       yield the baton once more just before enqueueing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
//       the stop-world CMS operation (executed by the VM thread).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
//   returns after all phases of the collection are done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
void CMSCollector::acquire_control_and_collect(bool full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
        bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
  assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
  assert(!Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
         "shouldn't try to acquire control from self!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
  // Start the protocol for acquiring control of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
  // collection from the background collector (aka CMS thread).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
  assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
         "VM thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1714
  // Remember the possibly interrupted state of an ongoing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
  // concurrent collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
  CollectorState first_state = _collectorState;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1717
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
  // Signal to a possibly ongoing concurrent collection that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
  // we want to do a foreground collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
  _foregroundGCIsActive = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
  // Disable incremental mode during a foreground collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
  ICMSDisabler icms_disabler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
  // release locks and wait for a notify from the background collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
  // releasing the locks in only necessary for phases which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
  // do yields to improve the granularity of the collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
  // We need to lock the Free list lock for the space that we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
  // currently collecting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
  assert(haveFreelistLocks(), "Must be holding free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
  bitMapLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
  releaseFreelistLocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
    if (_foregroundGCShouldWait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
      // We are going to be waiting for action for the CMS thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
      // it had better not be gone (for instance at shutdown)!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
      assert(ConcurrentMarkSweepThread::cmst() != NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
             "CMS thread must be running");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
      // Wait here until the background collector gives us the go-ahead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
      ConcurrentMarkSweepThread::clear_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
        ConcurrentMarkSweepThread::CMS_vm_has_token);  // release token
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
      // Get a possibly blocked CMS thread going:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
      //   Note that we set _foregroundGCIsActive true above,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
      //   without protection of the CGC_lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
      CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
      assert(!ConcurrentMarkSweepThread::vm_thread_wants_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
             "Possible deadlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
      while (_foregroundGCShouldWait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
        // wait for notification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
        CGC_lock->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
        // Possibility of delay/starvation here, since CMS token does
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
        // not know to give priority to VM thread? Actually, i think
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
        // there wouldn't be any delay/starvation, but the proof of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
        // that "fact" (?) appears non-trivial. XXX 20011219YSR
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
      ConcurrentMarkSweepThread::set_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
        ConcurrentMarkSweepThread::CMS_vm_has_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
  // The CMS_token is already held.  Get back the other locks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
  assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
         "VM thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
  getFreelistLocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
  bitMapLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
    gclog_or_tty->print_cr("CMS foreground collector has asked for control "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
      INTPTR_FORMAT " with first state %d", Thread::current(), first_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
    gclog_or_tty->print_cr("    gets control with state %d", _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
  // Check if we need to do a compaction, or if not, whether
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1774
  // we need to start the mark-sweep from scratch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1775
  bool should_compact    = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1776
  bool should_start_over = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
  decide_foreground_collection_type(clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
    &should_compact, &should_start_over);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1779
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1780
NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
  if (RotateCMSCollectionTypes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
    if (_cmsGen->debug_collection_type() ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1783
        ConcurrentMarkSweepGeneration::MSC_foreground_collection_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1784
      should_compact = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1785
    } else if (_cmsGen->debug_collection_type() ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
               ConcurrentMarkSweepGeneration::MS_foreground_collection_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1787
      should_compact = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1788
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1789
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1790
)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
  if (PrintGCDetails && first_state > Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
    GCCause::Cause cause = GenCollectedHeap::heap()->gc_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
    if (GCCause::is_user_requested_gc(cause) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
        GCCause::is_serviceability_requested_gc(cause)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
      gclog_or_tty->print(" (concurrent mode interrupted)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
      gclog_or_tty->print(" (concurrent mode failure)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1799
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
  if (should_compact) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
    // If the collection is being acquired from the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1804
    // collector, there may be references on the discovered
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1805
    // references lists that have NULL referents (being those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1806
    // that were concurrently cleared by a mutator) or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
    // that are no longer active (having been enqueued concurrently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
    // by the mutator).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
    // Scrub the list of those references because Mark-Sweep-Compact
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
    // code assumes referents are not NULL and that all discovered
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
    // Reference objects are active.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
    ref_processor()->clean_up_discovered_references();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
    do_compaction_work(clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
    // Has the GC time limit been exceeded?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
    check_gc_time_limit();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1819
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1820
    do_mark_sweep_work(clear_all_soft_refs, first_state,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1821
      should_start_over);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
  // Reset the expansion cause, now that we just completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
  // a collection cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1825
  clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
  _foregroundGCIsActive = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1828
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
void CMSCollector::check_gc_time_limit() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1831
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1832
  // Ignore explicit GC's.  Exiting here does not set the flag and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1833
  // does not reset the count.  Updating of the averages for system
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1834
  // GC's is still controlled by UseAdaptiveSizePolicyWithSystemGC.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1835
  GCCause::Cause gc_cause = GenCollectedHeap::heap()->gc_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1836
  if (GCCause::is_user_requested_gc(gc_cause) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1837
      GCCause::is_serviceability_requested_gc(gc_cause)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
  // Calculate the fraction of the CMS generation was freed during
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
  // the last collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
  // Only consider the STW compacting cost for now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
  // Note that the gc time limit test only works for the collections
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
  // of the young gen + tenured gen and not for collections of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
  // permanent gen.  That is because the calculation of the space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1848
  // freed by the collection is the free space in the young gen +
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
  // tenured gen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1850
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1851
  double fraction_free =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
    ((double)_cmsGen->free())/((double)_cmsGen->max_capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
  if ((100.0 * size_policy()->compacting_gc_cost()) >
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1854
         ((double) GCTimeLimit) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1855
        ((fraction_free * 100) < GCHeapFreeLimit)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1856
    size_policy()->inc_gc_time_limit_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1857
    if (UseGCOverheadLimit &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1858
        (size_policy()->gc_time_limit_count() >
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1859
         AdaptiveSizePolicyGCTimeLimitThreshold)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1860
      size_policy()->set_gc_time_limit_exceeded(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1861
      // Avoid consecutive OOM due to the gc time limit by resetting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1862
      // the counter.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1863
      size_policy()->reset_gc_time_limit_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1864
      if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1865
        gclog_or_tty->print_cr("      GC is exceeding overhead limit "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1866
          "of %d%%", GCTimeLimit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1867
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
      if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
        gclog_or_tty->print_cr("      GC would exceed overhead limit "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
          "of %d%%", GCTimeLimit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1872
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1875
    size_policy()->reset_gc_time_limit_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1876
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1877
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1878
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1879
// Resize the perm generation and the tenured generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1880
// after obtaining the free list locks for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1881
// two generations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1882
void CMSCollector::compute_new_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1883
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1884
  FreelistLocker z(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1885
  _permGen->compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1886
  _cmsGen->compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1887
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1888
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1889
// A work method used by foreground collection to determine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1890
// what type of collection (compacting or not, continuing or fresh)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1891
// it should do.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1892
// NOTE: the intent is to make UseCMSCompactAtFullCollection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1893
// and CMSCompactWhenClearAllSoftRefs the default in the future
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1894
// and do away with the flags after a suitable period.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1895
void CMSCollector::decide_foreground_collection_type(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1896
  bool clear_all_soft_refs, bool* should_compact,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1897
  bool* should_start_over) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1898
  // Normally, we'll compact only if the UseCMSCompactAtFullCollection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1899
  // flag is set, and we have either requested a System.gc() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1900
  // the number of full gc's since the last concurrent cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1901
  // has exceeded the threshold set by CMSFullGCsBeforeCompaction,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
  // or if an incremental collection has failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
  assert(gch->collector_policy()->is_two_generation_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
         "You may want to check the correctness of the following");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
  // Inform cms gen if this was due to partial collection failing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
  // The CMS gen may use this fact to determine its expansion policy.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
  if (gch->incremental_collection_will_fail()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
    assert(!_cmsGen->incremental_collection_failed(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
           "Should have been noticed, reacted to and cleared");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
    _cmsGen->set_incremental_collection_failed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
  *should_compact =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
    UseCMSCompactAtFullCollection &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
    ((_full_gcs_since_conc_gc >= CMSFullGCsBeforeCompaction) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
     GCCause::is_user_requested_gc(gch->gc_cause()) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
     gch->incremental_collection_will_fail());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
  *should_start_over = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
  if (clear_all_soft_refs && !*should_compact) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
    // We are about to do a last ditch collection attempt
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
    // so it would normally make sense to do a compaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
    // to reclaim as much space as possible.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
    if (CMSCompactWhenClearAllSoftRefs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
      // Default: The rationale is that in this case either
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
      // we are past the final marking phase, in which case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
      // we'd have to start over, or so little has been done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
      // that there's little point in saving that work. Compaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
      // appears to be the sensible choice in either case.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
      *should_compact = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
      // We have been asked to clear all soft refs, but not to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
      // compact. Make sure that we aren't past the final checkpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
      // phase, for that is where we process soft refs. If we are already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
      // past that phase, we'll need to redo the refs discovery phase and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
      // if necessary clear soft refs that weren't previously
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
      // cleared. We do so by remembering the phase in which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
      // we came in, and if we are past the refs processing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
      // phase, we'll choose to just redo the mark-sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
      // collection from scratch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
      if (_collectorState > FinalMarking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
        // We are past the refs processing phase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
        // start over and do a fresh synchronous CMS cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
        _collectorState = Resetting; // skip to reset to start new cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
        reset(false /* == !asynch */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
        *should_start_over = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
      } // else we can continue a possibly ongoing current cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
// A work method used by the foreground collector to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
// a mark-sweep-compact.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
  TraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
  if (PrintGC && Verbose && !(GCCause::is_user_requested_gc(gch->gc_cause()))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1957
    gclog_or_tty->print_cr("Compact ConcurrentMarkSweepGeneration after %d "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1958
      "collections passed to foreground collector", _full_gcs_since_conc_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1959
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1961
  // Sample collection interval time and reset for collection pause.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1962
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1963
    size_policy()->msc_collection_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1964
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1965
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1966
  // Temporarily widen the span of the weak reference processing to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
  // the entire heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1968
  MemRegion new_span(GenCollectedHeap::heap()->reserved_region());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1969
  ReferenceProcessorSpanMutator x(ref_processor(), new_span);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
  // Temporarily, clear the "is_alive_non_header" field of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
  // reference processor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1973
  ReferenceProcessorIsAliveMutator y(ref_processor(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
  // Temporarily make reference _processing_ single threaded (non-MT).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
  ReferenceProcessorMTProcMutator z(ref_processor(), false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1978
  // Temporarily make refs discovery atomic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1979
  ReferenceProcessorAtomicMutator w(ref_processor(), true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1981
  ref_processor()->set_enqueuing_is_done(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1982
  ref_processor()->enable_discovery();
1610
5dddd195cc86 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 1606
diff changeset
  1983
  ref_processor()->setup_policy(clear_all_soft_refs);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1984
  // If an asynchronous collection finishes, the _modUnionTable is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1985
  // all clear.  If we are assuming the collection from an asynchronous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1986
  // collection, clear the _modUnionTable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1987
  assert(_collectorState != Idling || _modUnionTable.isAllClear(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1988
    "_modUnionTable should be clear if the baton was not passed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1989
  _modUnionTable.clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1990
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1991
  // We must adjust the allocation statistics being maintained
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1992
  // in the free list space. We do so by reading and clearing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1993
  // the sweep timer and updating the block flux rate estimates below.
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  1994
  assert(!_intra_sweep_timer.is_active(), "_intra_sweep_timer should be inactive");
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  1995
  if (_inter_sweep_timer.is_active()) {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  1996
    _inter_sweep_timer.stop();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  1997
    // Note that we do not use this sample to update the _inter_sweep_estimate.
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  1998
    _cmsGen->cmsSpace()->beginSweepFLCensus((float)(_inter_sweep_timer.seconds()),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  1999
                                            _inter_sweep_estimate.padded_average(),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2000
                                            _intra_sweep_estimate.padded_average());
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2001
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2003
  GenMarkSweep::invoke_at_safepoint(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2004
    ref_processor(), clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2005
  #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
    CompactibleFreeListSpace* cms_space = _cmsGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
    size_t free_size = cms_space->free();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2008
    assert(free_size ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
           pointer_delta(cms_space->end(), cms_space->compaction_top())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
           * HeapWordSize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
      "All the free space should be compacted into one chunk at top");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
    assert(cms_space->dictionary()->totalChunkSize(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
                                      debug_only(cms_space->freelistLock())) == 0 ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
           cms_space->totalSizeInIndexedFreeLists() == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
      "All the free space should be in a single chunk");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
    size_t num = cms_space->totalCount();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
    assert((free_size == 0 && num == 0) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
           (free_size > 0  && (num == 1 || num == 2)),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
         "There should be at most 2 free chunks after compaction");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
  #endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2021
  _collectorState = Resetting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
  assert(_restart_addr == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
         "Should have been NULL'd before baton was passed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2024
  reset(false /* == !asynch */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
  _cmsGen->reset_after_compaction();
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2026
  _concurrent_cycles_since_last_unload = 0;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2027
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2028
  if (verifying() && !should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2029
    perm_gen_verify_bit_map()->clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
  // Clear any data recorded in the PLAB chunk arrays.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
  if (_survivor_plab_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2034
    reset_survivor_plab_arrays();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
  // Adjust the per-size allocation stats for the next epoch.
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2038
  _cmsGen->cmsSpace()->endSweepFLCensus(sweep_count() /* fake */);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2039
  // Restart the "inter sweep timer" for the next epoch.
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2040
  _inter_sweep_timer.reset();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2041
  _inter_sweep_timer.start();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2042
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2043
  // Sample collection pause time and reset for collection interval.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
    size_policy()->msc_collection_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2047
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
  // For a mark-sweep-compact, compute_new_size() will be called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
  // in the heap's do_collection() method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2052
// A work method used by the foreground collector to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2053
// a mark-sweep, after taking over from a possibly on-going
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2054
// concurrent mark-sweep collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2055
void CMSCollector::do_mark_sweep_work(bool clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2056
  CollectorState first_state, bool should_start_over) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2057
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2058
    gclog_or_tty->print_cr("Pass concurrent collection to foreground "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2059
      "collector with count %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2060
      _full_gcs_since_conc_gc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2061
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2062
  switch (_collectorState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2063
    case Idling:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2064
      if (first_state == Idling || should_start_over) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2065
        // The background GC was not active, or should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2066
        // restarted from scratch;  start the cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2067
        _collectorState = InitialMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2068
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2069
      // If first_state was not Idling, then a background GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2070
      // was in progress and has now finished.  No need to do it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2071
      // again.  Leave the state as Idling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2072
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2073
    case Precleaning:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2074
      // In the foreground case don't do the precleaning since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2075
      // it is not done concurrently and there is extra work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2076
      // required.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2077
      _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2078
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2079
  if (PrintGCDetails &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2080
      (_collectorState > Idling ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2081
       !GCCause::is_user_requested_gc(GenCollectedHeap::heap()->gc_cause()))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2082
    gclog_or_tty->print(" (concurrent mode failure)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2083
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2084
  collect_in_foreground(clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2085
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2086
  // For a mark-sweep, compute_new_size() will be called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2087
  // in the heap's do_collection() method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2088
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2089
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2090
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2091
void CMSCollector::getFreelistLocks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2092
  // Get locks for all free lists in all generations that this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2093
  // collector is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2094
  _cmsGen->freelistLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2095
  _permGen->freelistLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2096
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2097
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2098
void CMSCollector::releaseFreelistLocks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2099
  // Release locks for all free lists in all generations that this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2100
  // collector is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2101
  _cmsGen->freelistLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2102
  _permGen->freelistLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2103
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
bool CMSCollector::haveFreelistLocks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2106
  // Check locks for all free lists in all generations that this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2107
  // collector is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
  assert_lock_strong(_cmsGen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
  assert_lock_strong(_permGen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
  PRODUCT_ONLY(ShouldNotReachHere());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2114
// A utility class that is used by the CMS collector to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
// temporarily "release" the foreground collector from its
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
// usual obligation to wait for the background collector to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
// complete an ongoing phase before proceeding.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2118
class ReleaseForegroundGC: public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
  CMSCollector* _c;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
  ReleaseForegroundGC(CMSCollector* c) : _c(c) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
    assert(_c->_foregroundGCShouldWait, "Else should not need to call");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
    // allow a potentially blocked foreground collector to proceed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
    _c->_foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
    if (_c->_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
      CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
    assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
           "Possible deadlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2133
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2134
  ~ReleaseForegroundGC() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
    assert(!_c->_foregroundGCShouldWait, "Usage protocol violation?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2136
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2137
    _c->_foregroundGCShouldWait = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2138
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2139
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2140
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2141
// There are separate collect_in_background and collect_in_foreground because of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2142
// the different locking requirements of the background collector and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2143
// foreground collector.  There was originally an attempt to share
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2144
// one "collect" method between the background collector and the foreground
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2145
// collector but the if-then-else required made it cleaner to have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2146
// separate methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2147
void CMSCollector::collect_in_background(bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2148
  assert(Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2149
    "A CMS asynchronous collection is only allowed on a CMS thread.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2150
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2151
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2152
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2153
    bool safepoint_check = Mutex::_no_safepoint_check_flag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2154
    MutexLockerEx hl(Heap_lock, safepoint_check);
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2155
    FreelistLocker fll(this);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2156
    MutexLockerEx x(CGC_lock, safepoint_check);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2157
    if (_foregroundGCIsActive || !UseAsyncConcMarkSweepGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2158
      // The foreground collector is active or we're
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2159
      // not using asynchronous collections.  Skip this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2160
      // background collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2161
      assert(!_foregroundGCShouldWait, "Should be clear");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2162
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2163
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2164
      assert(_collectorState == Idling, "Should be idling before start.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2165
      _collectorState = InitialMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2166
      // Reset the expansion cause, now that we are about to begin
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2167
      // a new cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2168
      clear_expansion_cause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2169
    }
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2170
    // 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
  2171
    // ensuing concurrent GC cycle.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  2172
    update_should_unload_classes();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
    _full_gc_requested = false;           // acks all outstanding full gc requests
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
    // Signal that we are about to start a collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
    gch->increment_total_full_collections();  // ... starting a collection cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
    _collection_count_start = gch->total_full_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2179
  // Used for PrintGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2180
  size_t prev_used;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2181
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
    prev_used = _cmsGen->used(); // XXXPERM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2185
  // The change of the collection state is normally done at this level;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2186
  // the exceptions are phases that are executed while the world is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2187
  // stopped.  For those phases the change of state is done while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
  // world is stopped.  For baton passing purposes this allows the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2189
  // background collector to finish the phase and change state atomically.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
  // The foreground collector cannot wait on a phase that is done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
  // while the world is stopped because the foreground collector already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2192
  // has the world stopped and would deadlock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
  while (_collectorState != Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2195
      gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " in CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2196
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2197
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2198
    // The foreground collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2199
    //   holds the Heap_lock throughout its collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2200
    //   holds the CMS token (but not the lock)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2201
    //     except while it is waiting for the background collector to yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2202
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2203
    // The foreground collector should be blocked (not for long)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
    //   if the background collector is about to start a phase
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
    //   executed with world stopped.  If the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
    //   collector has already started such a phase, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2207
    //   foreground collector is blocked waiting for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2208
    //   Heap_lock.  The stop-world phases (InitialMarking and FinalMarking)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2209
    //   are executed in the VM thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2211
    // The locking order is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
    //   PendingListLock (PLL)  -- if applicable (FinalMarking)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
    //   Heap_lock  (both this & PLL locked in VM_CMS_Operation::prologue())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
    //   CMS token  (claimed in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
    //                stop_world_and_do() -->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
    //                  safepoint_synchronize() -->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
    //                    CMSThread::synchronize())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
      // Check if the FG collector wants us to yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
      CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
      if (waitForForegroundGC()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
        // We yielded to a foreground GC, nothing more to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2224
        // done this round.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2225
        assert(_foregroundGCShouldWait == false, "We set it to false in "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2226
               "waitForForegroundGC()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2227
        if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2228
          gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2229
            " exiting collection CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2230
            Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2231
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2232
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
        // The background collector can run but check to see if the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
        // foreground collector has done a collection while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
        // background collector was waiting to get the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
        // above.  If yes, break so that _foregroundGCShouldWait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
        // is cleared before returning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
        if (_collectorState == Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
    assert(_foregroundGCShouldWait, "Foreground collector, if active, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
      "should be waiting");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
    switch (_collectorState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
      case InitialMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
          ReleaseForegroundGC x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
          stats().record_cms_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2254
          VM_CMS_Initial_Mark initial_mark_op(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
          VMThread::execute(&initial_mark_op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
        // The collector state may be any legal state at this point
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
        // since the background collector may have yielded to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2259
        // foreground collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2260
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2261
      case Marking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
        // initial marking in checkpointRootsInitialWork has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
        if (markFromRoots(true)) { // we were successful
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
          assert(_collectorState == Precleaning, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
            "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
          assert(_foregroundGCIsActive, "Internal state inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
      case Precleaning:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
          size_policy()->concurrent_precleaning_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2273
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
        // marking from roots in markFromRoots has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
        preclean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
          size_policy()->concurrent_precleaning_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
        assert(_collectorState == AbortablePreclean ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
               _collectorState == FinalMarking,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
               "Collector state should have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
      case AbortablePreclean:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
        size_policy()->concurrent_phases_resume();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2286
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
        abortable_preclean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2288
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
          size_policy()->concurrent_precleaning_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
        assert(_collectorState == FinalMarking, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
          "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
      case FinalMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
          ReleaseForegroundGC x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
          VM_CMS_Final_Remark final_remark_op(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
          VMThread::execute(&final_remark_op);
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  2300
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
        assert(_foregroundGCShouldWait, "block post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
      case Sweeping:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
          size_policy()->concurrent_sweeping_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
        // final marking in checkpointRootsFinal has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
        sweep(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
        assert(_collectorState == Resizing, "Collector state change "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
          "to Resizing must be done under the free_list_lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
        _full_gcs_since_conc_gc = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2313
        // Stop the timers for adaptive size policy for the concurrent phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2314
        if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
          size_policy()->concurrent_sweeping_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
          size_policy()->concurrent_phases_end(gch->gc_cause(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2317
                                             gch->prev_gen(_cmsGen)->capacity(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2318
                                             _cmsGen->free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2320
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
      case Resizing: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
        // Sweeping has been completed...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
        // At this point the background collection has completed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2324
        // Don't move the call to compute_new_size() down
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
        // into code that might be executed if the background
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
        // collection was preempted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
          ReleaseForegroundGC x(this);   // unblock FG collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
          MutexLockerEx       y(Heap_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
          CMSTokenSync        z(true);   // not strictly needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
          if (_collectorState == Resizing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
            compute_new_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
            _collectorState = Resetting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2335
            assert(_collectorState == Idling, "The state should only change"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2336
                   " because the foreground collector has finished the collection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2337
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2338
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2339
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2340
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2341
      case Resetting:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
        // CMS heap resizing has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2343
        reset(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
        assert(_collectorState == Idling, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
          "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
        stats().record_cms_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
        // Don't move the concurrent_phases_end() and compute_new_size()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
        // calls to here because a preempted background collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
        // has it's state set to "Resetting".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
      case Idling:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
        ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
        break;
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("  Thread " INTPTR_FORMAT " done - next CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2360
    assert(_foregroundGCShouldWait, "block post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2361
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2362
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2363
  // Should this be in gc_epilogue?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
  collector_policy()->counters()->update_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2365
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2366
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2367
    // Clear _foregroundGCShouldWait and, in the event that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2368
    // foreground collector is waiting, notify it, before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2369
    // returning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2370
    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2371
    _foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2372
    if (_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2373
      CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2374
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2375
    assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2376
           "Possible deadlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2377
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2378
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2379
    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
      " exiting collection CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2381
      Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2382
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2383
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
    _cmsGen->print_heap_change(prev_used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2386
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2387
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2388
void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
  assert(_foregroundGCIsActive && !_foregroundGCShouldWait,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2390
         "Foreground collector should be waiting, not executing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
  assert(Thread::current()->is_VM_thread(), "A foreground collection"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
    "may only be done by the VM Thread with the world stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2393
  assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
         "VM thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2396
  NOT_PRODUCT(TraceTime t("CMS:MS (foreground) ", PrintGCDetails && Verbose,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2397
    true, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
    size_policy()->ms_collection_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
  COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
  HandleMark hm;  // Discard invalid handles created during verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
  if (VerifyBeforeGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2409
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  2410
  // Snapshot the soft reference policy to be used in this collection cycle.
1610
5dddd195cc86 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 1606
diff changeset
  2411
  ref_processor()->setup_policy(clear_all_soft_refs);
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  2412
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
  bool init_mark_was_synchronous = false; // until proven otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
  while (_collectorState != Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
      gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " in CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
    switch (_collectorState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
      case InitialMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
        init_mark_was_synchronous = true;  // fact to be exploited in re-mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
        checkpointRootsInitial(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
        assert(_collectorState == Marking, "Collector state should have changed"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
          " within checkpointRootsInitial()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
      case Marking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
        // initial marking in checkpointRootsInitialWork has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
          gclog_or_tty->print("Verify before initial mark: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2431
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2432
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2433
        {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2434
          bool res = markFromRoots(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2435
          assert(res && _collectorState == FinalMarking, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2436
            "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2437
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2438
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2439
      case FinalMarking:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2440
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2441
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2442
          gclog_or_tty->print("Verify before re-mark: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2443
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2444
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2445
        checkpointRootsFinal(false, clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2446
                             init_mark_was_synchronous);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2447
        assert(_collectorState == Sweeping, "Collector state should not "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2448
          "have changed within checkpointRootsFinal()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2449
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2450
      case Sweeping:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2451
        // final marking in checkpointRootsFinal has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2452
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2453
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2454
          gclog_or_tty->print("Verify before sweep: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2455
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2456
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2457
        sweep(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2458
        assert(_collectorState == Resizing, "Incorrect state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2459
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2460
      case Resizing: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2461
        // Sweeping has been completed; the actual resize in this case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2462
        // is done separately; nothing to be done in this state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2463
        _collectorState = Resetting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2464
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2465
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2466
      case Resetting:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2467
        // The heap has been resized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2468
        if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2469
            GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2470
          gclog_or_tty->print("Verify before reset: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2471
          Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2472
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2473
        reset(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2474
        assert(_collectorState == Idling, "Collector state should "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2475
          "have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2476
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2477
      case Precleaning:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2478
      case AbortablePreclean:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2479
        // Elide the preclean phase
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2480
        _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2481
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2482
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2483
        ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2484
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2485
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2486
      gclog_or_tty->print_cr("  Thread " INTPTR_FORMAT " done - next CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2487
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2488
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2489
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2490
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2491
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2492
    GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2493
    size_policy()->ms_collection_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2494
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2495
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2496
  if (VerifyAfterGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2497
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2498
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2499
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2500
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2501
    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2502
      " exiting collection CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2503
      Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2504
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2505
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2506
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2507
bool CMSCollector::waitForForegroundGC() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2508
  bool res = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2509
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2510
         "CMS thread should have CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2511
  // Block the foreground collector until the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
  // background collectors decides whether to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2513
  // yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2514
  MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2515
  _foregroundGCShouldWait = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2516
  if (_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
    // The background collector yields to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
    // foreground collector and returns a value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2519
    // indicating that it has yielded.  The foreground
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
    // collector can proceed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2521
    res = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
    _foregroundGCShouldWait = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
    ConcurrentMarkSweepThread::clear_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2524
      ConcurrentMarkSweepThread::CMS_cms_has_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2525
    ConcurrentMarkSweepThread::set_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2526
      ConcurrentMarkSweepThread::CMS_cms_wants_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
    // Get a possibly blocked foreground thread going
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2528
    CGC_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2529
    if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
      gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT " waiting at CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2531
        Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2533
    while (_foregroundGCIsActive) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2534
      CGC_lock->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2535
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2536
    ConcurrentMarkSweepThread::set_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2537
      ConcurrentMarkSweepThread::CMS_cms_has_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
    ConcurrentMarkSweepThread::clear_CMS_flag(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
      ConcurrentMarkSweepThread::CMS_cms_wants_token);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2540
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
  if (TraceCMSState) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT " continuing at CMS state %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
      Thread::current(), _collectorState);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
// Because of the need to lock the free lists and other structures in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
// the collector, common to all the generations that the collector is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
// collecting, we need the gc_prologues of individual CMS generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2551
// delegate to their collector. It may have been simpler had the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2552
// current infrastructure allowed one to call a prologue on a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2553
// collector. In the absence of that we have the generation's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
// prologue delegate to the collector, which delegates back
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
// some "local" work to a worker method in the individual generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2556
// that it's responsible for collecting, while itself doing any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2557
// work common to all generations it's responsible for. A similar
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2558
// comment applies to the  gc_epilogue()'s.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2559
// The role of the varaible _between_prologue_and_epilogue is to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2560
// enforce the invocation protocol.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2561
void CMSCollector::gc_prologue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
  // Call gc_prologue_work() for each CMSGen and PermGen that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
  // we are responsible for.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2564
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2565
  // The following locking discipline assumes that we are only called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2566
  // when the world is stopped.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2567
  assert(SafepointSynchronize::is_at_safepoint(), "world is stopped assumption");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2568
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2569
  // The CMSCollector prologue must call the gc_prologues for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2570
  // "generations" (including PermGen if any) that it's responsible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2571
  // for.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2572
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2573
  assert(   Thread::current()->is_VM_thread()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2574
         || (   CMSScavengeBeforeRemark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
             && Thread::current()->is_ConcurrentGC_thread()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2576
         "Incorrect thread type for prologue execution");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
  if (_between_prologue_and_epilogue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2579
    // We have already been invoked; this is a gc_prologue delegation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2580
    // from yet another CMS generation that we are responsible for, just
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
    // ignore it since all relevant work has already been done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
  // set a bit saying prologue has been called; cleared in epilogue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
  _between_prologue_and_epilogue = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
  // Claim locks for common data structures, then call gc_prologue_work()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
  // for each CMSGen and PermGen that we are responsible for.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2590
  getFreelistLocks();   // gets free list locks on constituent spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2591
  bitMapLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2592
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2593
  // Should call gc_prologue_work() for all cms gens we are responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2594
  bool registerClosure =    _collectorState >= Marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
                         && _collectorState < Sweeping;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
  ModUnionClosure* muc = ParallelGCThreads > 0 ? &_modUnionClosurePar
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
                                               : &_modUnionClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
  _cmsGen->gc_prologue_work(full, registerClosure, muc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
  _permGen->gc_prologue_work(full, registerClosure, muc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
  if (!full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
    stats().record_gc0_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2604
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
void ConcurrentMarkSweepGeneration::gc_prologue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
  // Delegate to CMScollector which knows how to coordinate between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
  // this and any other CMS generations that it is responsible for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
  // collecting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2610
  collector()->gc_prologue(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2613
// This is a "private" interface for use by this generation's CMSCollector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2614
// Not to be called directly by any other entity (for instance,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2615
// GenCollectedHeap, which calls the "public" gc_prologue method above).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2616
void ConcurrentMarkSweepGeneration::gc_prologue_work(bool full,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2617
  bool registerClosure, ModUnionClosure* modUnionClosure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2618
  assert(!incremental_collection_failed(), "Shouldn't be set yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2619
  assert(cmsSpace()->preconsumptionDirtyCardClosure() == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2620
    "Should be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2621
  if (registerClosure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2622
    cmsSpace()->setPreconsumptionDirtyCardClosure(modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2623
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
  cmsSpace()->gc_prologue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
  // Clear stat counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2626
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
    assert(_numObjectsPromoted == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2628
    assert(_numWordsPromoted   == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2629
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2630
      gclog_or_tty->print("Allocated "SIZE_FORMAT" objects, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2631
                          SIZE_FORMAT" bytes concurrently",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
      _numObjectsAllocated, _numWordsAllocated*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2633
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2634
    _numObjectsAllocated = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2635
    _numWordsAllocated   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2636
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2637
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2638
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2639
void CMSCollector::gc_epilogue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2640
  // The following locking discipline assumes that we are only called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2641
  // when the world is stopped.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2642
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2643
         "world is stopped assumption");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2644
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2645
  // Currently the CMS epilogue (see CompactibleFreeListSpace) merely checks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2646
  // if linear allocation blocks need to be appropriately marked to allow the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2647
  // the blocks to be parsable. We also check here whether we need to nudge the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2648
  // CMS collector thread to start a new cycle (if it's not already active).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2649
  assert(   Thread::current()->is_VM_thread()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2650
         || (   CMSScavengeBeforeRemark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2651
             && Thread::current()->is_ConcurrentGC_thread()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2652
         "Incorrect thread type for epilogue execution");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2653
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2654
  if (!_between_prologue_and_epilogue) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2655
    // We have already been invoked; this is a gc_epilogue delegation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2656
    // from yet another CMS generation that we are responsible for, just
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2657
    // ignore it since all relevant work has already been done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2658
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2659
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2660
  assert(haveFreelistLocks(), "must have freelist locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2661
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2662
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2663
  _cmsGen->gc_epilogue_work(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2664
  _permGen->gc_epilogue_work(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2665
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2666
  if (_collectorState == AbortablePreclean || _collectorState == Precleaning) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2667
    // in case sampling was not already enabled, enable it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2668
    _start_sampling = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2669
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2670
  // reset _eden_chunk_array so sampling starts afresh
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2671
  _eden_chunk_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2672
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2673
  size_t cms_used   = _cmsGen->cmsSpace()->used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2674
  size_t perm_used  = _permGen->cmsSpace()->used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2675
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2676
  // update performance counters - this uses a special version of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2677
  // update_counters() that allows the utilization to be passed as a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2678
  // parameter, avoiding multiple calls to used().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2679
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2680
  _cmsGen->update_counters(cms_used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2681
  _permGen->update_counters(perm_used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2682
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2683
  if (CMSIncrementalMode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2684
    icms_update_allocation_limits();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2685
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2686
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2687
  bitMapLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2688
  releaseFreelistLocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2689
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2690
  _between_prologue_and_epilogue = false;  // ready for next cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2691
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2692
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2693
void ConcurrentMarkSweepGeneration::gc_epilogue(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2694
  collector()->gc_epilogue(full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2695
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2696
  // Also reset promotion tracking in par gc thread states.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2697
  if (ParallelGCThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2698
    for (uint i = 0; i < ParallelGCThreads; i++) {
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2699
      _par_gc_thread_states[i]->promo.stopTrackingPromotions(i);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2700
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2701
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2702
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2703
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2704
void ConcurrentMarkSweepGeneration::gc_epilogue_work(bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2705
  assert(!incremental_collection_failed(), "Should have been cleared");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2706
  cmsSpace()->setPreconsumptionDirtyCardClosure(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2707
  cmsSpace()->gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2708
    // Print stat counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2709
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2710
    assert(_numObjectsAllocated == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2711
    assert(_numWordsAllocated == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2712
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2713
      gclog_or_tty->print("Promoted "SIZE_FORMAT" objects, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2714
                          SIZE_FORMAT" bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2715
                 _numObjectsPromoted, _numWordsPromoted*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2716
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2717
    _numObjectsPromoted = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2718
    _numWordsPromoted   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2719
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2720
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2721
  if (PrintGC && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2722
    // Call down the chain in contiguous_available needs the freelistLock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2723
    // so print this out before releasing the freeListLock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2724
    gclog_or_tty->print(" Contiguous available "SIZE_FORMAT" bytes ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2725
                        contiguous_available());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2726
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2727
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2728
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2729
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2730
bool CMSCollector::have_cms_token() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2731
  Thread* thr = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2732
  if (thr->is_VM_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2733
    return ConcurrentMarkSweepThread::vm_thread_has_cms_token();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2734
  } else if (thr->is_ConcurrentGC_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2735
    return ConcurrentMarkSweepThread::cms_thread_has_cms_token();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2736
  } else if (thr->is_GC_task_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2737
    return ConcurrentMarkSweepThread::vm_thread_has_cms_token() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2738
           ParGCRareEvent_lock->owned_by_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2739
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2740
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2741
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2742
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2743
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2744
// Check reachability of the given heap address in CMS generation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2745
// treating all other generations as roots.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2746
bool CMSCollector::is_cms_reachable(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2747
  // We could "guarantee" below, rather than assert, but i'll
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2748
  // leave these as "asserts" so that an adventurous debugger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2749
  // could try this in the product build provided some subset of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2750
  // the conditions were met, provided they were intersted in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2751
  // results and knew that the computation below wouldn't interfere
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2752
  // with other concurrent computations mutating the structures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2753
  // being read or written.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2754
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2755
         "Else mutations in object graph will make answer suspect");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2756
  assert(have_cms_token(), "Should hold cms token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2757
  assert(haveFreelistLocks(), "must hold free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2758
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2759
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2760
  // Clear the marking bit map array before starting, but, just
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2761
  // for kicks, first report if the given address is already marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2762
  gclog_or_tty->print_cr("Start: Address 0x%x is%s marked", addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2763
                _markBitMap.isMarked(addr) ? "" : " not");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2764
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2765
  if (verify_after_remark()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2766
    MutexLockerEx x(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2767
    bool result = verification_mark_bm()->isMarked(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2768
    gclog_or_tty->print_cr("TransitiveMark: Address 0x%x %s marked", addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2769
                           result ? "IS" : "is NOT");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2770
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2771
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2772
    gclog_or_tty->print_cr("Could not compute result");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2773
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2774
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2775
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2776
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2777
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2778
// CMS Verification Support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2779
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2780
// Following the remark phase, the following invariant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2781
// should hold -- each object in the CMS heap which is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2782
// marked in markBitMap() should be marked in the verification_mark_bm().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2784
class VerifyMarkedClosure: public BitMapClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2785
  CMSBitMap* _marks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2786
  bool       _failed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2787
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2788
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2789
  VerifyMarkedClosure(CMSBitMap* bm): _marks(bm), _failed(false) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2790
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  2791
  bool do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2792
    HeapWord* addr = _marks->offsetToHeapWord(offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2793
    if (!_marks->isMarked(addr)) {
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2794
      oop(addr)->print_on(gclog_or_tty);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2795
      gclog_or_tty->print_cr(" ("INTPTR_FORMAT" should have been marked)", addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2796
      _failed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2797
    }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  2798
    return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2799
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2800
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2801
  bool failed() { return _failed; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2802
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2803
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2804
bool CMSCollector::verify_after_remark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2805
  gclog_or_tty->print(" [Verifying CMS Marking... ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2806
  MutexLockerEx ml(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2807
  static bool init = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2808
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2809
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2810
         "Else mutations in object graph will make answer suspect");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2811
  assert(have_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2812
         "Else there may be mutual interference in use of "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2813
         " verification data structures");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2814
  assert(_collectorState > Marking && _collectorState <= Sweeping,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2815
         "Else marking info checked here may be obsolete");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2816
  assert(haveFreelistLocks(), "must hold free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2817
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2818
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2819
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2820
  // Allocate marking bit map if not already allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2821
  if (!init) { // first time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2822
    if (!verification_mark_bm()->allocate(_span)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2823
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2824
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2825
    init = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2826
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2827
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2828
  assert(verification_mark_stack()->isEmpty(), "Should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2829
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2830
  // Turn off refs discovery -- so we will be tracing through refs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2831
  // This is as intended, because by this time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2832
  // GC must already have cleared any refs that need to be cleared,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2833
  // and traced those that need to be marked; moreover,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2834
  // the marking done here is not going to intefere in any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2835
  // way with the marking information used by GC.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2836
  NoRefDiscovery no_discovery(ref_processor());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2837
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2838
  COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2839
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2840
  // Clear any marks from a previous round
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2841
  verification_mark_bm()->clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2842
  assert(verification_mark_stack()->isEmpty(), "markStack should be empty");
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2843
  verify_work_stacks_empty();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2844
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2845
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2846
  gch->ensure_parsability(false);  // fill TLABs, but no need to retire them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2847
  // Update the saved marks which may affect the root scans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2848
  gch->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2849
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2850
  if (CMSRemarkVerifyVariant == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2851
    // In this first variant of verification, we complete
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2852
    // all marking, then check if the new marks-verctor is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2853
    // a subset of the CMS marks-vector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2854
    verify_after_remark_work_1();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2855
  } else if (CMSRemarkVerifyVariant == 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2856
    // In this second variant of verification, we flag an error
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2857
    // (i.e. an object reachable in the new marks-vector not reachable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2858
    // in the CMS marks-vector) immediately, also indicating the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2859
    // identify of an object (A) that references the unmarked object (B) --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2860
    // presumably, a mutation to A failed to be picked up by preclean/remark?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2861
    verify_after_remark_work_2();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2862
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2863
    warning("Unrecognized value %d for CMSRemarkVerifyVariant",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2864
            CMSRemarkVerifyVariant);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2865
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2866
  gclog_or_tty->print(" done] ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2867
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2868
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2869
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2870
void CMSCollector::verify_after_remark_work_1() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2871
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2872
  HandleMark  hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2873
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2874
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2875
  // Mark from roots one level into CMS
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  2876
  MarkRefsIntoClosure notOlder(_span, verification_mark_bm());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2877
  gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2878
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2879
  gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2880
                                true,   // younger gens are roots
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2881
                                true,   // activate StrongRootsScope
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2882
                                true,   // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2883
                                SharedHeap::ScanningOption(roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2884
                                &notOlder,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2885
                                true,   // walk code active on stacks
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2886
                                NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2887
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2888
  // Now mark from the roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2889
  assert(_revisitStack.isEmpty(), "Should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2890
  MarkFromRootsClosure markFromRootsClosure(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2891
    verification_mark_bm(), verification_mark_stack(), &_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2892
    false /* don't yield */, true /* verifying */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2893
  assert(_restart_addr == NULL, "Expected pre-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2894
  verification_mark_bm()->iterate(&markFromRootsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2895
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2896
    // Deal with stack overflow: by restarting at the indicated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2897
    // address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2898
    HeapWord* ra = _restart_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2899
    markFromRootsClosure.reset(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2900
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2901
    verification_mark_bm()->iterate(&markFromRootsClosure, ra, _span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2902
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2903
  assert(verification_mark_stack()->isEmpty(), "Should have been drained");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2904
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2905
  // Should reset the revisit stack above, since no class tree
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2906
  // surgery is forthcoming.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2907
  _revisitStack.reset(); // throwing away all contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2908
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2909
  // Marking completed -- now verify that each bit marked in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2910
  // verification_mark_bm() is also marked in markBitMap(); flag all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2911
  // errors by printing corresponding objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2912
  VerifyMarkedClosure vcl(markBitMap());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2913
  verification_mark_bm()->iterate(&vcl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2914
  if (vcl.failed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2915
    gclog_or_tty->print("Verification failed");
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2916
    Universe::heap()->print_on(gclog_or_tty);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  2917
    fatal("CMS: failed marking verification after remark");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2918
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2919
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2920
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2921
void CMSCollector::verify_after_remark_work_2() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2922
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2923
  HandleMark  hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2924
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2925
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2926
  // Mark from roots one level into CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2927
  MarkRefsIntoVerifyClosure notOlder(_span, verification_mark_bm(),
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  2928
                                     markBitMap());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2929
  gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2930
  gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2931
                                true,   // younger gens are roots
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2932
                                true,   // activate StrongRootsScope
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2933
                                true,   // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2934
                                SharedHeap::ScanningOption(roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2935
                                &notOlder,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2936
                                true,   // walk code active on stacks
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  2937
                                NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2938
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2939
  // Now mark from the roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2940
  assert(_revisitStack.isEmpty(), "Should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2941
  MarkFromRootsVerifyClosure markFromRootsClosure(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2942
    verification_mark_bm(), markBitMap(), verification_mark_stack());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2943
  assert(_restart_addr == NULL, "Expected pre-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2944
  verification_mark_bm()->iterate(&markFromRootsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2945
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2946
    // Deal with stack overflow: by restarting at the indicated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2947
    // address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2948
    HeapWord* ra = _restart_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2949
    markFromRootsClosure.reset(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2950
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2951
    verification_mark_bm()->iterate(&markFromRootsClosure, ra, _span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2952
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2953
  assert(verification_mark_stack()->isEmpty(), "Should have been drained");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2954
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2955
  // Should reset the revisit stack above, since no class tree
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2956
  // surgery is forthcoming.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2957
  _revisitStack.reset(); // throwing away all contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2958
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2959
  // Marking completed -- now verify that each bit marked in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2960
  // verification_mark_bm() is also marked in markBitMap(); flag all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2961
  // errors by printing corresponding objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2962
  VerifyMarkedClosure vcl(markBitMap());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2963
  verification_mark_bm()->iterate(&vcl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2964
  assert(!vcl.failed(), "Else verification above should not have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2965
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2966
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2967
void ConcurrentMarkSweepGeneration::save_marks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2968
  // delegate to CMS space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2969
  cmsSpace()->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2970
  for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2971
    _par_gc_thread_states[i]->promo.startTrackingPromotions();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2972
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2973
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2974
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2975
bool ConcurrentMarkSweepGeneration::no_allocs_since_save_marks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2976
  return cmsSpace()->no_allocs_since_save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2977
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2978
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2979
#define CMS_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix)    \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2980
                                                                \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2981
void ConcurrentMarkSweepGeneration::                            \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2982
oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) {   \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2983
  cl->set_generation(this);                                     \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2984
  cmsSpace()->oop_since_save_marks_iterate##nv_suffix(cl);      \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2985
  cl->reset_generation();                                       \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2986
  save_marks();                                                 \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2987
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2988
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2989
ALL_SINCE_SAVE_MARKS_CLOSURES(CMS_SINCE_SAVE_MARKS_DEFN)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2990
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2991
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2992
ConcurrentMarkSweepGeneration::object_iterate_since_last_GC(ObjectClosure* blk)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2993
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2994
  // Not currently implemented; need to do the following. -- ysr.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2995
  // dld -- I think that is used for some sort of allocation profiler.  So it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2996
  // really means the objects allocated by the mutator since the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2997
  // GC.  We could potentially implement this cheaply by recording only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2998
  // the direct allocations in a side data structure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2999
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3000
  // I think we probably ought not to be required to support these
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3001
  // iterations at any arbitrary point; I think there ought to be some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3002
  // call to enable/disable allocation profiling in a generation/space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3003
  // and the iterator ought to return the objects allocated in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3004
  // gen/space since the enable call, or the last iterator call (which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3005
  // will probably be at a GC.)  That way, for gens like CM&S that would
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3006
  // require some extra data structure to support this, we only pay the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3007
  // cost when it's in use...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3008
  cmsSpace()->object_iterate_since_last_GC(blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3009
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3010
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3011
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3012
ConcurrentMarkSweepGeneration::younger_refs_iterate(OopsInGenClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3013
  cl->set_generation(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3014
  younger_refs_in_space_iterate(_cmsSpace, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3015
  cl->reset_generation();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3016
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3018
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3019
ConcurrentMarkSweepGeneration::oop_iterate(MemRegion mr, OopClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3020
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3021
    Generation::oop_iterate(mr, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3022
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3023
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3024
    Generation::oop_iterate(mr, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3025
  }
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::oop_iterate(OopClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3030
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3031
    Generation::oop_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3032
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3033
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3034
    Generation::oop_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3035
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3036
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3037
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3038
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3039
ConcurrentMarkSweepGeneration::object_iterate(ObjectClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3040
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3041
    Generation::object_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3042
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3043
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3044
    Generation::object_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3045
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3046
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3047
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3048
void
1893
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3049
ConcurrentMarkSweepGeneration::safe_object_iterate(ObjectClosure* cl) {
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3050
  if (freelistLock()->owned_by_self()) {
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3051
    Generation::safe_object_iterate(cl);
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3052
  } else {
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3053
    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3054
    Generation::safe_object_iterate(cl);
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3055
  }
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3056
}
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3057
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1610
diff changeset
  3058
void
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3059
ConcurrentMarkSweepGeneration::pre_adjust_pointers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3060
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3061
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3062
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3063
ConcurrentMarkSweepGeneration::post_compact() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3064
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3065
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3066
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3067
ConcurrentMarkSweepGeneration::prepare_for_verify() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3068
  // Fix the linear allocation blocks to look like free blocks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3069
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3070
  // Locks are normally acquired/released in gc_prologue/gc_epilogue, but those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3071
  // are not called when the heap is verified during universe initialization and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3072
  // at vm shutdown.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3073
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3074
    cmsSpace()->prepare_for_verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3075
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3076
    MutexLockerEx fll(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3077
    cmsSpace()->prepare_for_verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3078
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3079
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3080
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3081
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3082
ConcurrentMarkSweepGeneration::verify(bool allow_dirty /* ignored */) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3083
  // Locks are normally acquired/released in gc_prologue/gc_epilogue, but those
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3084
  // are not called when the heap is verified during universe initialization and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3085
  // at vm shutdown.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3086
  if (freelistLock()->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3087
    cmsSpace()->verify(false /* ignored */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3088
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3089
    MutexLockerEx fll(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3090
    cmsSpace()->verify(false /* ignored */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3091
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3092
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3093
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3094
void CMSCollector::verify(bool allow_dirty /* ignored */) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3095
  _cmsGen->verify(allow_dirty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3096
  _permGen->verify(allow_dirty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3097
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3098
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3099
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3100
bool CMSCollector::overflow_list_is_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3101
  assert(_num_par_pushes >= 0, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3102
  if (_overflow_list == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3103
    assert(_num_par_pushes == 0, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3104
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3105
  return _overflow_list == NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3106
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3107
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3108
// The methods verify_work_stacks_empty() and verify_overflow_empty()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3109
// merely consolidate assertion checks that appear to occur together frequently.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3110
void CMSCollector::verify_work_stacks_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3111
  assert(_markStack.isEmpty(), "Marking stack should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3112
  assert(overflow_list_is_empty(), "Overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3113
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3114
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3115
void CMSCollector::verify_overflow_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3116
  assert(overflow_list_is_empty(), "Overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3117
  assert(no_preserved_marks(), "No preserved marks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3118
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3119
#endif // PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3120
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3121
// 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
  3122
// 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
  3123
// unload classes if it's the case that:
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3124
// (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
  3125
//     ExplicitGCInvokesConcurrentAndUnloadsClasses is set, OR
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3126
// (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
  3127
//     (b) (i)   perm gen threshold has been crossed, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3128
//         (ii)  old gen is getting really full, or
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3129
//         (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
  3130
//               perm gen
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3131
// 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
  3132
// 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
  3133
// 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
  3134
// 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
  3135
// 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
  3136
// the property that concurrent_cycles_since_last_unload()
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3137
// 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
  3138
// _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
  3139
// themselves also monotonic in that sense. See check_monotonicity()
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3140
// below.
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3141
bool CMSCollector::update_should_unload_classes() {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3142
  _should_unload_classes = false;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3143
  // Condition 1 above
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3144
  if (_full_gc_requested && ExplicitGCInvokesConcurrentAndUnloadsClasses) {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3145
    _should_unload_classes = true;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3146
  } else if (CMSClassUnloadingEnabled) { // Condition 2.a above
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3147
    // Disjuncts 2.b.(i,ii,iii) above
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3148
    _should_unload_classes = (concurrent_cycles_since_last_unload() >=
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3149
                              CMSClassUnloadingMaxInterval)
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3150
                           || _permGen->should_concurrent_collect()
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3151
                           || _cmsGen->is_too_full();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3152
  }
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3153
  return _should_unload_classes;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3154
}
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3155
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3156
bool ConcurrentMarkSweepGeneration::is_too_full() const {
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3157
  bool res = should_concurrent_collect();
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3158
  res = res && (occupancy() > (double)CMSIsTooFullPercentage/100.0);
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3159
  return res;
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3160
}
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3161
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3162
void CMSCollector::setup_cms_unloading_and_verification_state() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3163
  const  bool should_verify =    VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3164
                             || VerifyBeforeExit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3165
  const  int  rso           =    SharedHeap::SO_Symbols | SharedHeap::SO_Strings
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3166
                             |   SharedHeap::SO_CodeCache;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3167
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3168
  if (should_unload_classes()) {   // Should unload classes this cycle
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3169
    remove_root_scanning_option(rso);  // Shrink the root set appropriately
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3170
    set_verifying(should_verify);    // Set verification state for this cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3171
    return;                            // Nothing else needs to be done at this time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3172
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3173
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3174
  // Not unloading classes this cycle
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3175
  assert(!should_unload_classes(), "Inconsitency!");
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  3176
  if ((!verifying() || unloaded_classes_last_cycle()) && should_verify) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3177
    // We were not verifying, or we _were_ unloading classes in the last cycle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3178
    // AND some verification options are enabled this cycle; in this case,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3179
    // we must make sure that the deadness map is allocated if not already so,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3180
    // and cleared (if already allocated previously --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3181
    // CMSBitMap::sizeInBits() is used to determine if it's allocated).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3182
    if (perm_gen_verify_bit_map()->sizeInBits() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3183
      if (!perm_gen_verify_bit_map()->allocate(_permGen->reserved())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3184
        warning("Failed to allocate permanent generation verification CMS Bit Map;\n"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3185
                "permanent generation verification disabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3186
        return;  // Note that we leave verification disabled, so we'll retry this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3187
                 // allocation next cycle. We _could_ remember this failure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3188
                 // and skip further attempts and permanently disable verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3189
                 // attempts if that is considered more desirable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3190
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3191
      assert(perm_gen_verify_bit_map()->covers(_permGen->reserved()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3192
              "_perm_gen_ver_bit_map inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3193
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3194
      perm_gen_verify_bit_map()->clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3195
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3196
    // Include symbols, strings and code cache elements to prevent their resurrection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3197
    add_root_scanning_option(rso);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3198
    set_verifying(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3199
  } else if (verifying() && !should_verify) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3200
    // We were verifying, but some verification flags got disabled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3201
    set_verifying(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3202
    // Exclude symbols, strings and code cache elements from root scanning to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3203
    // reduce IM and RM pauses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3204
    remove_root_scanning_option(rso);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3205
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3206
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3207
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3208
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3209
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3210
HeapWord* CMSCollector::block_start(const void* p) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3211
  const HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3212
  if (_span.contains(p)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3213
    if (_cmsGen->cmsSpace()->is_in_reserved(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3214
      return _cmsGen->cmsSpace()->block_start(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3215
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3216
      assert(_permGen->cmsSpace()->is_in_reserved(addr),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3217
             "Inconsistent _span?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3218
      return _permGen->cmsSpace()->block_start(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3219
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3220
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3221
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3222
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3223
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3224
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3225
HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3226
ConcurrentMarkSweepGeneration::expand_and_allocate(size_t word_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3227
                                                   bool   tlab,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3228
                                                   bool   parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3229
  assert(!tlab, "Can't deal with TLAB allocation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3230
  MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3231
  expand(word_size*HeapWordSize, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3232
    CMSExpansionCause::_satisfy_allocation);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3233
  if (GCExpandToAllocateDelayMillis > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3234
    os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3235
  }
182
eae79d9b9d46 6642634: Test nsk/regression/b6186200 crashed with SIGSEGV
ysr
parents: 180
diff changeset
  3236
  return have_lock_and_allocate(word_size, tlab);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3237
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3238
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3239
// YSR: All of this generation expansion/shrinking stuff is an exact copy of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3240
// OneContigSpaceCardGeneration, which makes me wonder if we should move this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3241
// to CardGeneration and share it...
979
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3242
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
  3243
  return CardGeneration::expand(bytes, expand_bytes);
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3244
}
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3245
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3246
void ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3247
  CMSExpansionCause::Cause cause)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3248
{
979
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3249
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3250
  bool success = expand(bytes, expand_bytes);
c9479f1e0a94 6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents: 670
diff changeset
  3251
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3252
  // remember why we expanded; this information is used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3253
  // by shouldConcurrentCollect() when making decisions on whether to start
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3254
  // a new CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3255
  if (success) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3256
    set_expansion_cause(cause);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3257
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3258
      gclog_or_tty->print_cr("Expanded CMS gen for %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3259
        CMSExpansionCause::to_string(cause));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3260
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3261
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3262
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3263
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3264
HeapWord* ConcurrentMarkSweepGeneration::expand_and_par_lab_allocate(CMSParGCThreadState* ps, size_t word_sz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3265
  HeapWord* res = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3266
  MutexLocker x(ParGCRareEvent_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3267
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3268
    // Expansion by some other thread might make alloc OK now:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3269
    res = ps->lab.alloc(word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3270
    if (res != NULL) return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3271
    // If there's not enough expansion space available, give up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3272
    if (_virtual_space.uncommitted_size() < (word_sz * HeapWordSize)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3273
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3274
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3275
    // Otherwise, we try expansion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3276
    expand(word_sz*HeapWordSize, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3277
      CMSExpansionCause::_allocate_par_lab);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3278
    // Now go around the loop and try alloc again;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3279
    // A competing par_promote might beat us to the expansion space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3280
    // so we may go around the loop again if promotion fails agaion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3281
    if (GCExpandToAllocateDelayMillis > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3282
      os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3283
    }
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
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3288
bool ConcurrentMarkSweepGeneration::expand_and_ensure_spooling_space(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3289
  PromotionInfo* promo) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3290
  MutexLocker x(ParGCRareEvent_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3291
  size_t refill_size_bytes = promo->refillSize() * HeapWordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3292
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3293
    // Expansion by some other thread might make alloc OK now:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3294
    if (promo->ensure_spooling_space()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3295
      assert(promo->has_spooling_space(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3296
             "Post-condition of successful ensure_spooling_space()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3297
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3298
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3299
    // If there's not enough expansion space available, give up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3300
    if (_virtual_space.uncommitted_size() < refill_size_bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3301
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3302
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3303
    // Otherwise, we try expansion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3304
    expand(refill_size_bytes, MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3305
      CMSExpansionCause::_allocate_par_spooling_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3306
    // Now go around the loop and try alloc again;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3307
    // A competing allocation might beat us to the expansion space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3308
    // so we may go around the loop again if allocation fails again.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3309
    if (GCExpandToAllocateDelayMillis > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3310
      os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3311
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3312
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3313
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3314
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3315
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3316
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3317
void ConcurrentMarkSweepGeneration::shrink(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3318
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3319
  size_t size = ReservedSpace::page_align_size_down(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3320
  if (size > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3321
    shrink_by(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3322
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3323
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3324
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3325
bool ConcurrentMarkSweepGeneration::grow_by(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3326
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3327
  bool result = _virtual_space.expand_by(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3328
  if (result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3329
    HeapWord* old_end = _cmsSpace->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3330
    size_t new_word_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3331
      heap_word_size(_virtual_space.committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3332
    MemRegion mr(_cmsSpace->bottom(), new_word_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3333
    _bts->resize(new_word_size);  // resize the block offset shared array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3334
    Universe::heap()->barrier_set()->resize_covered_region(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3335
    // Hmmmm... why doesn't CFLS::set_end verify locking?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3336
    // This is quite ugly; FIX ME XXX
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  3337
    _cmsSpace->assert_locked(freelistLock());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3338
    _cmsSpace->set_end((HeapWord*)_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3339
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3340
    // update the space and generation capacity counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3341
    if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3342
      _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3343
      _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3344
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3345
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3346
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3347
      size_t new_mem_size = _virtual_space.committed_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3348
      size_t old_mem_size = new_mem_size - bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3349
      gclog_or_tty->print_cr("Expanding %s from %ldK by %ldK to %ldK",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3350
                    name(), old_mem_size/K, bytes/K, new_mem_size/K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3351
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3352
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3353
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3354
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3355
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3356
bool ConcurrentMarkSweepGeneration::grow_to_reserved() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3357
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3358
  bool success = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3359
  const size_t remaining_bytes = _virtual_space.uncommitted_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3360
  if (remaining_bytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3361
    success = grow_by(remaining_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3362
    DEBUG_ONLY(if (!success) warning("grow to reserved failed");)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3363
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3364
  return success;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3365
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3366
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3367
void ConcurrentMarkSweepGeneration::shrink_by(size_t bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3368
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3369
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3370
  // XXX Fix when compaction is implemented.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3371
  warning("Shrinking of CMS not yet implemented");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3372
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3373
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3374
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3375
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3376
// Simple ctor/dtor wrapper for accounting & timer chores around concurrent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3377
// phases.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3378
class CMSPhaseAccounting: public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3379
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3380
  CMSPhaseAccounting(CMSCollector *collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3381
                     const char *phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3382
                     bool print_cr = true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3383
  ~CMSPhaseAccounting();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3384
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3385
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3386
  CMSCollector *_collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3387
  const char *_phase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3388
  elapsedTimer _wallclock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3389
  bool _print_cr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3390
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3391
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3392
  // Not MT-safe; so do not pass around these StackObj's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3393
  // where they may be accessed by other threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3394
  jlong wallclock_millis() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3395
    assert(_wallclock.is_active(), "Wall clock should not stop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3396
    _wallclock.stop();  // to record time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3397
    jlong ret = _wallclock.milliseconds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3398
    _wallclock.start(); // restart
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3399
    return ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3400
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3401
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3402
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3403
CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3404
                                       const char *phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3405
                                       bool print_cr) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3406
  _collector(collector), _phase(phase), _print_cr(print_cr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3407
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3408
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3409
    _collector->resetYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3410
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3411
  if (PrintGCDetails && PrintGCTimeStamps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3412
    gclog_or_tty->date_stamp(PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3413
    gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3414
    gclog_or_tty->print_cr(": [%s-concurrent-%s-start]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3415
      _collector->cmsGen()->short_name(), _phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3416
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3417
  _collector->resetTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3418
  _wallclock.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3419
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3420
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3421
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3422
CMSPhaseAccounting::~CMSPhaseAccounting() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3423
  assert(_wallclock.is_active(), "Wall clock should not have stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3424
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3425
  _wallclock.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3426
  if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3427
    gclog_or_tty->date_stamp(PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3428
    if (PrintGCTimeStamps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3429
      gclog_or_tty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3430
      gclog_or_tty->print(": ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3431
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3432
    gclog_or_tty->print("[%s-concurrent-%s: %3.3f/%3.3f secs]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3433
                 _collector->cmsGen()->short_name(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3434
                 _phase, _collector->timerValue(), _wallclock.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3435
    if (_print_cr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3436
      gclog_or_tty->print_cr("");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3437
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3438
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3439
      gclog_or_tty->print_cr(" (CMS-concurrent-%s yielded %d times)", _phase,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3440
                    _collector->yields());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3441
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3442
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3443
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3444
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3445
// CMS work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3446
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3447
// Checkpoint the roots into this generation from outside
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3448
// this generation. [Note this initial checkpoint need only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3449
// be approximate -- we'll do a catch up phase subsequently.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3450
void CMSCollector::checkpointRootsInitial(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3451
  assert(_collectorState == InitialMarking, "Wrong collector state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3452
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3453
  ReferenceProcessor* rp = ref_processor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3454
  SpecializationStats::clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3455
  assert(_restart_addr == NULL, "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3456
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3457
    // acquire locks for subsequent manipulations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3458
    MutexLockerEx x(bitMapLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3459
                    Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3460
    checkpointRootsInitialWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3461
    rp->verify_no_references_recorded();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3462
    rp->enable_discovery(); // enable ("weak") refs discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3463
    _collectorState = Marking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3464
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3465
    // (Weak) Refs discovery: this is controlled from genCollectedHeap::do_collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3466
    // which recognizes if we are a CMS generation, and doesn't try to turn on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3467
    // discovery; verify that they aren't meddling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3468
    assert(!rp->discovery_is_atomic(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3469
           "incorrect setting of discovery predicate");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3470
    assert(!rp->discovery_enabled(), "genCollectedHeap shouldn't control "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3471
           "ref discovery for this generation kind");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3472
    // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3473
    checkpointRootsInitialWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3474
    rp->enable_discovery(); // now enable ("weak") refs discovery
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3475
    _collectorState = Marking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3476
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3477
  SpecializationStats::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3478
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3479
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3480
void CMSCollector::checkpointRootsInitialWork(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3481
  assert(SafepointSynchronize::is_at_safepoint(), "world should be stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3482
  assert(_collectorState == InitialMarking, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3483
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3484
  // If there has not been a GC[n-1] since last GC[n] cycle completed,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3485
  // precede our marking with a collection of all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3486
  // younger generations to keep floating garbage to a minimum.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3487
  // XXX: we won't do this for now -- it's an optimization to be done later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3488
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3489
  // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3490
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3491
  assert(_markBitMap.isAllClear(), "was reset at end of previous cycle");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3492
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3493
  // Setup the verification and class unloading state for this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3494
  // CMS collection cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3495
  setup_cms_unloading_and_verification_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3496
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3497
  NOT_PRODUCT(TraceTime t("\ncheckpointRootsInitialWork",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3498
    PrintGCDetails && Verbose, true, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3499
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3500
    size_policy()->checkpoint_roots_initial_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3501
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3502
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3503
  // Reset all the PLAB chunk arrays if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3504
  if (_survivor_plab_array != NULL && !CMSPLABRecordAlways) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3505
    reset_survivor_plab_arrays();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3506
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3507
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3508
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3509
  HandleMark  hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3510
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3511
  FalseClosure falseClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3512
  // In the case of a synchronous collection, we will elide the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3513
  // remark step, so it's important to catch all the nmethod oops
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  3514
  // in this step.
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  3515
  // The final 'true' flag to gen_process_strong_roots will ensure this.
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  3516
  // If 'async' is true, we can relax the nmethod tracing.
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  3517
  MarkRefsIntoClosure notOlder(_span, &_markBitMap);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3518
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3519
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3520
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3521
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3522
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3523
  gch->ensure_parsability(false);  // fill TLABs, but no need to retire them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3524
  // Update the saved marks which may affect the root scans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3525
  gch->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3526
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3527
  // weak reference processing has not started yet.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3528
  ref_processor()->set_enqueuing_is_done(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3529
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3530
  {
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  3531
    // This is not needed. DEBUG_ONLY(RememberKlassesChecker imx(true);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3532
    COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3533
    gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3534
    gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3535
                                  true,   // younger gens are roots
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  3536
                                  true,   // activate StrongRootsScope
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3537
                                  true,   // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3538
                                  SharedHeap::ScanningOption(roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  3539
                                  &notOlder,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  3540
                                  true,   // walk all of code cache if (so & SO_CodeCache)
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  3541
                                  NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3542
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3543
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3544
  // Clear mod-union table; it will be dirtied in the prologue of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3545
  // CMS generation per each younger generation collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3546
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3547
  assert(_modUnionTable.isAllClear(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3548
       "Was cleared in most recent final checkpoint phase"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3549
       " or no bits are set in the gc_prologue before the start of the next "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3550
       "subsequent marking phase.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3551
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3552
  // Temporarily disabled, since pre/post-consumption closures don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3553
  // care about precleaned cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3554
  #if 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3555
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3556
    MemRegion mr = MemRegion((HeapWord*)_virtual_space.low(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3557
                             (HeapWord*)_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3558
    _ct->ct_bs()->preclean_dirty_cards(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3559
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3560
  #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3561
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3562
  // Save the end of the used_region of the constituent generations
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3563
  // to be used to limit the extent of sweep in each generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3564
  save_sweep_limits();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3565
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3566
    size_policy()->checkpoint_roots_initial_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3567
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3568
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3569
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3570
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3571
bool CMSCollector::markFromRoots(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3572
  // we might be tempted to assert that:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3573
  // assert(asynch == !SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3574
  //        "inconsistent argument?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3575
  // However that wouldn't be right, because it's possible that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3576
  // a safepoint is indeed in progress as a younger generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3577
  // stop-the-world GC happens even as we mark in this generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3578
  assert(_collectorState == Marking, "inconsistent state?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3579
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3580
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3581
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3582
  bool res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3583
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3584
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3585
    // Start the timers for adaptive size policy for the concurrent phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3586
    // Do it here so that the foreground MS can use the concurrent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3587
    // timer since a foreground MS might has the sweep done concurrently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3588
    // or STW.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3589
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3590
      size_policy()->concurrent_marking_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3591
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3592
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3593
    // Weak ref discovery note: We may be discovering weak
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3594
    // refs in this generation concurrent (but interleaved) with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3595
    // weak ref discovery by a younger generation collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3596
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3597
    CMSTokenSyncWithLocks ts(true, bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3598
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3599
    CMSPhaseAccounting pa(this, "mark", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3600
    res = markFromRootsWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3601
    if (res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3602
      _collectorState = Precleaning;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3603
    } else { // We failed and a foreground collection wants to take over
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3604
      assert(_foregroundGCIsActive, "internal state inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3605
      assert(_restart_addr == NULL,  "foreground will restart from scratch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3606
      if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3607
        gclog_or_tty->print_cr("bailing out to foreground collection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3608
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3609
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3610
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3611
      size_policy()->concurrent_marking_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3612
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3613
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3614
    assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3615
           "inconsistent with asynch == false");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3616
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3617
      size_policy()->ms_collection_marking_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3618
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3619
    // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3620
    res = markFromRootsWork(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3621
    _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3622
    if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3623
      GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3624
      size_policy()->ms_collection_marking_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3625
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3626
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3627
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3628
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3629
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3630
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3631
bool CMSCollector::markFromRootsWork(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3632
  // iterate over marked bits in bit map, doing a full scan and mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3633
  // from these roots using the following algorithm:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3634
  // . if oop is to the right of the current scan pointer,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3635
  //   mark corresponding bit (we'll process it later)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3636
  // . else (oop is to left of current scan pointer)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3637
  //   push oop on marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3638
  // . drain the marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3639
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3640
  // Note that when we do a marking step we need to hold the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3641
  // bit map lock -- recall that direct allocation (by mutators)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3642
  // and promotion (by younger generation collectors) is also
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3643
  // marking the bit map. [the so-called allocate live policy.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3644
  // Because the implementation of bit map marking is not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3645
  // robust wrt simultaneous marking of bits in the same word,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3646
  // we need to make sure that there is no such interference
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3647
  // between concurrent such updates.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3648
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3649
  // already have locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3650
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3651
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3652
  // Clear the revisit stack, just in case there are any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3653
  // obsolete contents from a short-circuited previous CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3654
  _revisitStack.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3655
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3656
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3657
  assert(_revisitStack.isEmpty(), "tabula rasa");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3658
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  3659
  DEBUG_ONLY(RememberKlassesChecker cmx(CMSClassUnloadingEnabled);)
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  3660
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3661
  bool result = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3662
  if (CMSConcurrentMTEnabled && ParallelCMSThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3663
    result = do_marking_mt(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3664
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3665
    result = do_marking_st(asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3666
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3667
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3668
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3669
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3670
// Forward decl
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3671
class CMSConcMarkingTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3672
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3673
class CMSConcMarkingTerminator: public ParallelTaskTerminator {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3674
  CMSCollector*       _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3675
  CMSConcMarkingTask* _task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3676
  bool _yield;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3677
 protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3678
  virtual void yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3679
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3680
  // "n_threads" is the number of threads to be terminated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3681
  // "queue_set" is a set of work queues of other threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3682
  // "collector" is the CMS collector associated with this task terminator.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3683
  // "yield" indicates whether we need the gang as a whole to yield.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3684
  CMSConcMarkingTerminator(int n_threads, TaskQueueSetSuper* queue_set,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3685
                           CMSCollector* collector, bool yield) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3686
    ParallelTaskTerminator(n_threads, queue_set),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3687
    _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3688
    _yield(yield) { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3689
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3690
  void set_task(CMSConcMarkingTask* task) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3691
    _task = task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3692
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3693
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3694
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3695
// MT Concurrent Marking Task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3696
class CMSConcMarkingTask: public YieldingFlexibleGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3697
  CMSCollector* _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3698
  YieldingFlexibleWorkGang* _workers;        // the whole gang
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3699
  int           _n_workers;                  // requested/desired # workers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3700
  bool          _asynch;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3701
  bool          _result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3702
  CompactibleFreeListSpace*  _cms_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3703
  CompactibleFreeListSpace* _perm_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3704
  HeapWord*     _global_finger;
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3705
  HeapWord*     _restart_addr;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3706
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3707
  //  Exposed here for yielding support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3708
  Mutex* const _bit_map_lock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3709
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3710
  // The per thread work queues, available here for stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3711
  OopTaskQueueSet*  _task_queues;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3712
  CMSConcMarkingTerminator _term;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3713
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3714
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3715
  CMSConcMarkingTask(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3716
                 CompactibleFreeListSpace* cms_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3717
                 CompactibleFreeListSpace* perm_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3718
                 bool asynch, int n_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3719
                 YieldingFlexibleWorkGang* workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3720
                 OopTaskQueueSet* task_queues):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3721
    YieldingFlexibleGangTask("Concurrent marking done multi-threaded"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3722
    _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3723
    _cms_space(cms_space),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3724
    _perm_space(perm_space),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3725
    _asynch(asynch), _n_workers(n_workers), _result(true),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3726
    _workers(workers), _task_queues(task_queues),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3727
    _term(n_workers, task_queues, _collector, asynch),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3728
    _bit_map_lock(collector->bitMapLock())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3729
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3730
    assert(n_workers <= workers->total_workers(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3731
           "Else termination won't work correctly today"); // XXX FIX ME!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3732
    _requested_size = n_workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3733
    _term.set_task(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3734
    assert(_cms_space->bottom() < _perm_space->bottom(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3735
           "Finger incorrectly initialized below");
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3736
    _restart_addr = _global_finger = _cms_space->bottom();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3737
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3738
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3739
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3740
  OopTaskQueueSet* task_queues()  { return _task_queues; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3741
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3742
  OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3743
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3744
  HeapWord** global_finger_addr() { return &_global_finger; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3745
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3746
  CMSConcMarkingTerminator* terminator() { return &_term; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3747
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3748
  void work(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3749
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3750
  virtual void coordinator_yield();  // stuff done by coordinator
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3751
  bool result() { return _result; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3752
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3753
  void reset(HeapWord* ra) {
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3754
    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
  3755
    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
  3756
    assert(ra             <  _perm_space->end(), "ra too large");
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3757
    _restart_addr = _global_finger = ra;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3758
    _term.reset_for_reuse();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3759
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3760
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3761
  static bool get_work_from_overflow_stack(CMSMarkStack* ovflw_stk,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3762
                                           OopTaskQueue* work_q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3763
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3764
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3765
  void do_scan_and_mark(int i, CompactibleFreeListSpace* sp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3766
  void do_work_steal(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3767
  void bump_global_finger(HeapWord* f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3768
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3769
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3770
void CMSConcMarkingTerminator::yield() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3771
  if (ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3772
      !_collector->foregroundGCIsActive() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3773
      _yield) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3774
    _task->yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3775
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3776
    ParallelTaskTerminator::yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3777
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3778
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3779
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3780
////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3781
// Concurrent Marking Algorithm Sketch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3782
////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3783
// Until all tasks exhausted (both spaces):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3784
// -- claim next available chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3785
// -- bump global finger via CAS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3786
// -- find first object that starts in this chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3787
//    and start scanning bitmap from that position
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3788
// -- scan marked objects for oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3789
// -- CAS-mark target, and if successful:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3790
//    . if target oop is above global finger (volatile read)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3791
//      nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3792
//    . if target oop is in chunk and above local finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3793
//        then nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3794
//    . else push on work-queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3795
// -- Deal with possible overflow issues:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3796
//    . local work-queue overflow causes stuff to be pushed on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3797
//      global (common) overflow queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3798
//    . always first empty local work queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3799
//    . then get a batch of oops from global work queue if any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3800
//    . then do work stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3801
// -- When all tasks claimed (both spaces)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3802
//    and local work queue empty,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3803
//    then in a loop do:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3804
//    . check global overflow stack; steal a batch of oops and trace
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3805
//    . try to steal from other threads oif GOS is empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3806
//    . if neither is available, offer termination
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3807
// -- Terminate and return result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3808
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3809
void CMSConcMarkingTask::work(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3810
  elapsedTimer _timer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3811
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3812
  HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3813
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3814
  DEBUG_ONLY(_collector->verify_overflow_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3815
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3816
  // Before we begin work, our work queue should be empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3817
  assert(work_queue(i)->size() == 0, "Expected to be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3818
  // Scan the bitmap covering _cms_space, tracing through grey objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3819
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3820
  do_scan_and_mark(i, _cms_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3821
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3822
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3823
    gclog_or_tty->print_cr("Finished cms space scanning in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3824
      i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3825
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3826
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3827
  // ... do the same for the _perm_space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3828
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3829
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3830
  do_scan_and_mark(i, _perm_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3831
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3832
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3833
    gclog_or_tty->print_cr("Finished perm space scanning in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3834
      i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3835
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3836
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3837
  // ... do work stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3838
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3839
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3840
  do_work_steal(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3841
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3842
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3843
    gclog_or_tty->print_cr("Finished work stealing in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3844
      i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3845
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3846
  assert(_collector->_markStack.isEmpty(), "Should have been emptied");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3847
  assert(work_queue(i)->size() == 0, "Should have been emptied");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3848
  // Note that under the current task protocol, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3849
  // following assertion is true even of the spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3850
  // expanded since the completion of the concurrent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3851
  // marking. XXX This will likely change under a strict
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3852
  // ABORT semantics.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3853
  assert(_global_finger >  _cms_space->end() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3854
         _global_finger >= _perm_space->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3855
         "All tasks have been completed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3856
  DEBUG_ONLY(_collector->verify_overflow_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3857
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3858
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3859
void CMSConcMarkingTask::bump_global_finger(HeapWord* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3860
  HeapWord* read = _global_finger;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3861
  HeapWord* cur  = read;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3862
  while (f > read) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3863
    cur = read;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3864
    read = (HeapWord*) Atomic::cmpxchg_ptr(f, &_global_finger, cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3865
    if (cur == read) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3866
      // our cas succeeded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3867
      assert(_global_finger >= f, "protocol consistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3868
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3869
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3870
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3871
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3872
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3873
// This is really inefficient, and should be redone by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3874
// using (not yet available) block-read and -write interfaces to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3875
// stack and the work_queue. XXX FIX ME !!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3876
bool CMSConcMarkingTask::get_work_from_overflow_stack(CMSMarkStack* ovflw_stk,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3877
                                                      OopTaskQueue* work_q) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3878
  // Fast lock-free check
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3879
  if (ovflw_stk->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3880
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3881
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3882
  assert(work_q->size() == 0, "Shouldn't steal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3883
  MutexLockerEx ml(ovflw_stk->par_lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3884
                   Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3885
  // Grab up to 1/4 the size of the work queue
2346
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  3886
  size_t num = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3887
                    (size_t)ParGCDesiredObjsFromOverflowList);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3888
  num = MIN2(num, ovflw_stk->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3889
  for (int i = (int) num; i > 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3890
    oop cur = ovflw_stk->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3891
    assert(cur != NULL, "Counted wrong?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3892
    work_q->push(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3893
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3894
  return num > 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3895
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3896
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3897
void CMSConcMarkingTask::do_scan_and_mark(int i, CompactibleFreeListSpace* sp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3898
  SequentialSubTasksDone* pst = sp->conc_par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3899
  int n_tasks = pst->n_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3900
  // We allow that there may be no tasks to do here because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3901
  // we are restarting after a stack overflow.
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3902
  assert(pst->valid() || n_tasks == 0, "Uninitialized use?");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3903
  int nth_task = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3904
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3905
  HeapWord* aligned_start = sp->bottom();
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3906
  if (sp->used_region().contains(_restart_addr)) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3907
    // 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
  3908
    // for this space.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3909
    aligned_start =
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3910
      (HeapWord*)align_size_down((uintptr_t)_restart_addr,
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3911
                                 CardTableModRefBS::card_size);
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3912
  }
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3913
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3914
  size_t chunk_size = sp->marking_task_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3915
  while (!pst->is_task_claimed(/* reference */ nth_task)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3916
    // Having claimed the nth task in this space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3917
    // compute the chunk that it corresponds to:
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3918
    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
  3919
                               aligned_start + (nth_task+1)*chunk_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3920
    // Try and bump the global finger via a CAS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3921
    // note that we need to do the global finger bump
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3922
    // _before_ taking the intersection below, because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3923
    // the task corresponding to that region will be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3924
    // deemed done even if the used_region() expands
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3925
    // because of allocation -- as it almost certainly will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3926
    // during start-up while the threads yield in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3927
    // closure below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3928
    HeapWord* finger = span.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3929
    bump_global_finger(finger);   // atomically
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3930
    // There are null tasks here corresponding to chunks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3931
    // beyond the "top" address of the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3932
    span = span.intersection(sp->used_region());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3933
    if (!span.is_empty()) {  // Non-null task
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3934
      HeapWord* prev_obj;
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3935
      assert(!span.contains(_restart_addr) || nth_task == 0,
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3936
             "Inconsistency");
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3937
      if (nth_task == 0) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3938
        // 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
  3939
        if (span.contains(_restart_addr)) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3940
          // 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
  3941
          // we might additionally skip a chunk prefix.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3942
          prev_obj = _restart_addr;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3943
        } else {
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3944
          prev_obj = span.start();
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3945
        }
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3946
      } else {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3947
        // We want to skip the first object because
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3948
        // 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
  3949
        // that _starts_ in this span; a fortiori, any
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3950
        // object starting in an earlier span is scanned
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3951
        // as part of an earlier claimed task.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3952
        // 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
  3953
        // 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
  3954
        prev_obj = sp->block_start_careful(span.start());
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3955
        // 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
  3956
        // Printezis bits to avoid waiting for allocated
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3957
        // objects to become initialized/parsable.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3958
        while (prev_obj < span.start()) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3959
          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
  3960
          if (sz > 0) {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3961
            prev_obj += sz;
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3962
          } else {
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3963
            // 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
  3964
            // scanning, but that appears unavoidable, short of
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3965
            // locking the free list locks; see bug 6324141.
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3966
            break;
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  3967
          }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3968
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3969
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3970
      if (prev_obj < span.end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3971
        MemRegion my_span = MemRegion(prev_obj, span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3972
        // Do the marking work within a non-empty span --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3973
        // the last argument to the constructor indicates whether the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3974
        // iteration should be incremental with periodic yields.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3975
        Par_MarkFromRootsClosure cl(this, _collector, my_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3976
                                    &_collector->_markBitMap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3977
                                    work_queue(i),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3978
                                    &_collector->_markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3979
                                    &_collector->_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3980
                                    _asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3981
        _collector->_markBitMap.iterate(&cl, my_span.start(), my_span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3982
      } // else nothing to do for this task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3983
    }   // else nothing to do for this task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3984
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3985
  // We'd be tempted to assert here that since there are no
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3986
  // more tasks left to claim in this space, the global_finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3987
  // must exceed space->top() and a fortiori space->end(). However,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3988
  // that would not quite be correct because the bumping of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3989
  // global_finger occurs strictly after the claiming of a task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3990
  // so by the time we reach here the global finger may not yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3991
  // have been bumped up by the thread that claimed the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3992
  // task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3993
  pst->all_tasks_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3994
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3995
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  3996
class Par_ConcMarkingClosure: public Par_KlassRememberingOopClosure {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  3997
 private:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3998
  MemRegion     _span;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3999
  CMSBitMap*    _bit_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4000
  CMSMarkStack* _overflow_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4001
  OopTaskQueue* _work_queue;
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4002
 protected:
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4003
  DO_OOP_WORK_DEFN
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4004
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4005
  Par_ConcMarkingClosure(CMSCollector* collector, OopTaskQueue* work_queue,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4006
                         CMSBitMap* bit_map, CMSMarkStack* overflow_stack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4007
                         CMSMarkStack* revisit_stack):
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4008
    Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4009
    _span(_collector->_span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4010
    _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4011
    _bit_map(bit_map),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4012
    _overflow_stack(overflow_stack)
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4013
  { }
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4014
  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
  4015
  virtual void do_oop(narrowOop* p);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4016
  void trim_queue(size_t max);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4017
  void handle_stack_overflow(HeapWord* lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4018
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4019
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4020
// Grey object scanning during work stealing phase --
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4021
// the salient assumption here is that any references
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4022
// 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
  4023
// 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
  4024
// 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
  4025
// 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
  4026
void Par_ConcMarkingClosure::do_oop(oop obj) {
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  4027
  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
  4028
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4029
  // Check if oop points into the CMS generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4030
  // and is not marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4031
  if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4032
    // a white object ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4033
    // If we manage to "claim" the object, by being the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4034
    // first thread to mark it, then we push it on our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4035
    // marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4036
    if (_bit_map->par_mark(addr)) {     // ... now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4037
      // push on work queue (grey set)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4038
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4039
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4040
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4041
            _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4042
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4043
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4044
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4045
      )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4046
      if (simulate_overflow ||
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4047
          !(_work_queue->push(obj) || _overflow_stack->par_push(obj))) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4048
        // stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4049
        if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4050
          gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4051
                                 SIZE_FORMAT, _overflow_stack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4052
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4053
        // We cannot assert that the overflow stack is full because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4054
        // it may have been emptied since.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4055
        assert(simulate_overflow ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4056
               _work_queue->size() == _work_queue->max_elems(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4057
              "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4058
        handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4059
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4060
    } // Else, some other thread got there first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4061
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4062
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4063
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4064
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
  4065
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
  4066
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4067
void Par_ConcMarkingClosure::trim_queue(size_t max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4068
  while (_work_queue->size() > max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4069
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4070
    if (_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4071
      assert(new_oop->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4072
      assert(_bit_map->isMarked((HeapWord*)new_oop), "Grey object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4073
      assert(_span.contains((HeapWord*)new_oop), "Not in span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4074
      assert(new_oop->is_parsable(), "Should be parsable");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4075
      new_oop->oop_iterate(this);  // do_oop() above
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4076
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4077
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4078
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4079
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4080
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4081
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4082
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4083
void Par_ConcMarkingClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4084
  // 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
  4085
  // workers from interfering with the work done below.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4086
  MutexLockerEx ml(_overflow_stack->par_lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4087
                   Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4088
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4089
  HeapWord* ra = (HeapWord*)_overflow_stack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4090
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4091
  _overflow_stack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4092
  _overflow_stack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4093
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4094
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4095
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4096
void CMSConcMarkingTask::do_work_steal(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4097
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4098
  oop obj_to_scan;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4099
  CMSBitMap* bm = &(_collector->_markBitMap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4100
  CMSMarkStack* ovflw = &(_collector->_markStack);
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4101
  CMSMarkStack* revisit = &(_collector->_revisitStack);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4102
  int* seed = _collector->hash_seed(i);
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4103
  Par_ConcMarkingClosure cl(_collector, work_q, bm, ovflw, revisit);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4104
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4105
    cl.trim_queue(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4106
    assert(work_q->size() == 0, "Should have been emptied above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4107
    if (get_work_from_overflow_stack(ovflw, work_q)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4108
      // Can't assert below because the work obtained from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4109
      // overflow stack may already have been stolen from us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4110
      // assert(work_q->size() > 0, "Work from overflow stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4111
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4112
    } else if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4113
      assert(obj_to_scan->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4114
      assert(bm->isMarked((HeapWord*)obj_to_scan), "Grey object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4115
      obj_to_scan->oop_iterate(&cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4116
    } else if (terminator()->offer_termination()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4117
      assert(work_q->size() == 0, "Impossible!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4118
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4119
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4120
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4121
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4122
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4123
// This is run by the CMS (coordinator) thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4124
void CMSConcMarkingTask::coordinator_yield() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4125
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4126
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4127
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4128
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4129
  // First give up the locks, then yield, then re-lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4130
  // We should probably use a constructor/destructor idiom to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4131
  // do this unlock/lock or modify the MutexUnlocker class to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4132
  // serve our purpose. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4133
  assert_lock_strong(_bit_map_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4134
  _bit_map_lock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4135
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4136
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4137
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4138
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4139
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4140
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4141
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4142
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4143
  // It is possible for whichever thread initiated the yield request
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4144
  // not to get a chance to wake up and take the bitmap lock between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4145
  // this thread releasing it and reacquiring it. So, while the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4146
  // should_yield() flag is on, let's sleep for a bit to give the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4147
  // other thread a chance to wake up. The limit imposed on the number
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4148
  // of iterations is defensive, to avoid any unforseen circumstances
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4149
  // putting us into an infinite loop. Since it's always been this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4150
  // (coordinator_yield()) method that was observed to cause the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4151
  // problem, we are using a parameter (CMSCoordinatorYieldSleepCount)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4152
  // which is by default non-zero. For the other seven methods that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4153
  // also perform the yield operation, as are using a different
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4154
  // parameter (CMSYieldSleepCount) which is by default zero. This way we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4155
  // can enable the sleeping for those methods too, if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4156
  // See 6442774.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4157
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4158
  // We really need to reconsider the synchronization between the GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4159
  // thread and the yield-requesting threads in the future and we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4160
  // should really use wait/notify, which is the recommended
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4161
  // way of doing this type of interaction. Additionally, we should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4162
  // consolidate the eight methods that do the yield operation and they
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4163
  // are almost identical into one for better maintenability and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4164
  // readability. See 6445193.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4165
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4166
  // Tony 2006.06.29
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4167
  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
  4168
                   ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  4169
                   !CMSCollector::foregroundGCIsActive(); ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4170
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4171
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4172
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4173
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4174
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4175
  _bit_map_lock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4176
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4177
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4179
bool CMSCollector::do_marking_mt(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4180
  assert(ParallelCMSThreads > 0 && conc_workers() != NULL, "precondition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4181
  // In the future this would be determined ergonomically, based
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4182
  // on #cpu's, # active mutator threads (and load), and mutation rate.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4183
  int num_workers = ParallelCMSThreads;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4184
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4185
  CompactibleFreeListSpace* cms_space  = _cmsGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4186
  CompactibleFreeListSpace* perm_space = _permGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4187
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4188
  CMSConcMarkingTask tsk(this, cms_space, perm_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4189
                         asynch, num_workers /* number requested XXX */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4190
                         conc_workers(), task_queues());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4191
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4192
  // Since the actual number of workers we get may be different
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4193
  // from the number we requested above, do we need to do anything different
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4194
  // below? In particular, may be we need to subclass the SequantialSubTasksDone
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4195
  // class?? XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4196
  cms_space ->initialize_sequential_subtasks_for_marking(num_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4197
  perm_space->initialize_sequential_subtasks_for_marking(num_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4198
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4199
  // Refs discovery is already non-atomic.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4200
  assert(!ref_processor()->discovery_is_atomic(), "Should be non-atomic");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4201
  // Mutate the Refs discovery so it is MT during the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4202
  // multi-threaded marking phase.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4203
  ReferenceProcessorMTMutator mt(ref_processor(), num_workers > 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4204
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4205
  DEBUG_ONLY(RememberKlassesChecker cmx(CMSClassUnloadingEnabled);)
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4206
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4207
  conc_workers()->start_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4208
  while (tsk.yielded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4209
    tsk.coordinator_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4210
    conc_workers()->continue_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4211
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4212
  // If the task was aborted, _restart_addr will be non-NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4213
  assert(tsk.completed() || _restart_addr != NULL, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4214
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4215
    // XXX For now we do not make use of ABORTED state and have not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4216
    // yet implemented the right abort semantics (even in the original
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4217
    // single-threaded CMS case). That needs some more investigation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4218
    // and is deferred for now; see CR# TBF. 07252005YSR. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4219
    assert(!CMSAbortSemantics || tsk.aborted(), "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4220
    // If _restart_addr is non-NULL, a marking stack overflow
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1910
diff changeset
  4221
    // occurred; we need to do a fresh marking iteration from the
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4222
    // indicated restart address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4223
    if (_foregroundGCIsActive && asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4224
      // We may be running into repeated stack overflows, having
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4225
      // reached the limit of the stack size, while making very
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4226
      // slow forward progress. It may be best to bail out and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4227
      // let the foreground collector do its job.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4228
      // Clear _restart_addr, so that foreground GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4229
      // works from scratch. This avoids the headache of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4230
      // a "rescan" which would otherwise be needed because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4231
      // of the dirty mod union table & card table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4232
      _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4233
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4234
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4235
    // Adjust the task to restart from _restart_addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4236
    tsk.reset(_restart_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4237
    cms_space ->initialize_sequential_subtasks_for_marking(num_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4238
                  _restart_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4239
    perm_space->initialize_sequential_subtasks_for_marking(num_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4240
                  _restart_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4241
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4242
    // Get the workers going again
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4243
    conc_workers()->start_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4244
    while (tsk.yielded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4245
      tsk.coordinator_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4246
      conc_workers()->continue_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4247
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4248
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4249
  assert(tsk.completed(), "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4250
  assert(tsk.result() == true, "Inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4251
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4252
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4253
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4254
bool CMSCollector::do_marking_st(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4255
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4256
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4257
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4258
  MarkFromRootsClosure markFromRootsClosure(this, _span, &_markBitMap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4259
    &_markStack, &_revisitStack, CMSYield && asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4260
  // the last argument to iterate indicates whether the iteration
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4261
  // should be incremental with periodic yields.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4262
  _markBitMap.iterate(&markFromRootsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4263
  // If _restart_addr is non-NULL, a marking stack overflow
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1910
diff changeset
  4264
  // occurred; we need to do a fresh iteration from the
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4265
  // indicated restart address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4266
  while (_restart_addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4267
    if (_foregroundGCIsActive && asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4268
      // We may be running into repeated stack overflows, having
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4269
      // reached the limit of the stack size, while making very
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4270
      // slow forward progress. It may be best to bail out and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4271
      // let the foreground collector do its job.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4272
      // Clear _restart_addr, so that foreground GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4273
      // works from scratch. This avoids the headache of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4274
      // a "rescan" which would otherwise be needed because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4275
      // of the dirty mod union table & card table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4276
      _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4277
      return false;  // indicating failure to complete marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4278
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4279
    // Deal with stack overflow:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4280
    // we restart marking from _restart_addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4281
    HeapWord* ra = _restart_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4282
    markFromRootsClosure.reset(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4283
    _restart_addr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4284
    _markBitMap.iterate(&markFromRootsClosure, ra, _span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4285
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4286
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4287
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4288
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4289
void CMSCollector::preclean() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4290
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4291
  assert(Thread::current()->is_ConcurrentGC_thread(), "Wrong thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4292
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4293
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4294
  _abort_preclean = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4295
  if (CMSPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4296
    _eden_chunk_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4297
    size_t used = get_eden_used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4298
    size_t capacity = get_eden_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4299
    // Don't start sampling unless we will get sufficiently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4300
    // many samples.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4301
    if (used < (capacity/(CMSScheduleRemarkSamplingRatio * 100)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4302
                * CMSScheduleRemarkEdenPenetration)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4303
      _start_sampling = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4304
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4305
      _start_sampling = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4306
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4307
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4308
    CMSPhaseAccounting pa(this, "preclean", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4309
    preclean_work(CMSPrecleanRefLists1, CMSPrecleanSurvivors1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4310
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4311
  CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4312
  if (CMSPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4313
    sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4314
    _collectorState = AbortablePreclean;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4315
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4316
    _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4317
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4318
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4319
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4320
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4321
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4322
// Try and schedule the remark such that young gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4323
// occupancy is CMSScheduleRemarkEdenPenetration %.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4324
void CMSCollector::abortable_preclean() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4325
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4326
  assert(CMSPrecleaningEnabled,  "Inconsistent control state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4327
  assert(_collectorState == AbortablePreclean, "Inconsistent control state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4328
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4329
  // If Eden's current occupancy is below this threshold,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4330
  // immediately schedule the remark; else preclean
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4331
  // past the next scavenge in an effort to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4332
  // schedule the pause as described avove. By choosing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4333
  // CMSScheduleRemarkEdenSizeThreshold >= max eden size
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4334
  // we will never do an actual abortable preclean cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4335
  if (get_eden_used() > CMSScheduleRemarkEdenSizeThreshold) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4336
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4337
    CMSPhaseAccounting pa(this, "abortable-preclean", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4338
    // We need more smarts in the abortable preclean
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4339
    // loop below to deal with cases where allocation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4340
    // in young gen is very very slow, and our precleaning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4341
    // is running a losing race against a horde of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4342
    // mutators intent on flooding us with CMS updates
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4343
    // (dirty cards).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4344
    // One, admittedly dumb, strategy is to give up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4345
    // after a certain number of abortable precleaning loops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4346
    // or after a certain maximum time. We want to make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4347
    // this smarter in the next iteration.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4348
    // XXX FIX ME!!! YSR
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4349
    size_t loops = 0, workdone = 0, cumworkdone = 0, waited = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4350
    while (!(should_abort_preclean() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4351
             ConcurrentMarkSweepThread::should_terminate())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4352
      workdone = preclean_work(CMSPrecleanRefLists2, CMSPrecleanSurvivors2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4353
      cumworkdone += workdone;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4354
      loops++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4355
      // Voluntarily terminate abortable preclean phase if we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4356
      // been at it for too long.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4357
      if ((CMSMaxAbortablePrecleanLoops != 0) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4358
          loops >= CMSMaxAbortablePrecleanLoops) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4359
        if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4360
          gclog_or_tty->print(" CMS: abort preclean due to loops ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4361
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4362
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4363
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4364
      if (pa.wallclock_millis() > CMSMaxAbortablePrecleanTime) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4365
        if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4366
          gclog_or_tty->print(" CMS: abort preclean due to time ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4367
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4368
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4369
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4370
      // If we are doing little work each iteration, we should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4371
      // take a short break.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4372
      if (workdone < CMSAbortablePrecleanMinWorkPerIteration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4373
        // Sleep for some time, waiting for work to accumulate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4374
        stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4375
        cmsThread()->wait_on_cms_lock(CMSAbortablePrecleanWaitMillis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4376
        startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4377
        waited++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4378
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4379
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4380
    if (PrintCMSStatistics > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4381
      gclog_or_tty->print(" [%d iterations, %d waits, %d cards)] ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4382
                          loops, waited, cumworkdone);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4383
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4384
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4385
  CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4386
  if (_collectorState != Idling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4387
    assert(_collectorState == AbortablePreclean,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4388
           "Spontaneous state transition?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4389
    _collectorState = FinalMarking;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4390
  } // Else, a foreground collection completed this CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4391
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4392
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4393
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4394
// Respond to an Eden sampling opportunity
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4395
void CMSCollector::sample_eden() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4396
  // Make sure a young gc cannot sneak in between our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4397
  // reading and recording of a sample.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4398
  assert(Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4399
         "Only the cms thread may collect Eden samples");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4400
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4401
         "Should collect samples while holding CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4402
  if (!_start_sampling) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4403
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4404
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4405
  if (_eden_chunk_array) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4406
    if (_eden_chunk_index < _eden_chunk_capacity) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4407
      _eden_chunk_array[_eden_chunk_index] = *_top_addr;   // take sample
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4408
      assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4409
             "Unexpected state of Eden");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4410
      // We'd like to check that what we just sampled is an oop-start address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4411
      // however, we cannot do that here since the object may not yet have been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4412
      // initialized. So we'll instead do the check when we _use_ this sample
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4413
      // later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4414
      if (_eden_chunk_index == 0 ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4415
          (pointer_delta(_eden_chunk_array[_eden_chunk_index],
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4416
                         _eden_chunk_array[_eden_chunk_index-1])
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4417
           >= CMSSamplingGrain)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4418
        _eden_chunk_index++;  // commit sample
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4419
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4420
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4421
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4422
  if ((_collectorState == AbortablePreclean) && !_abort_preclean) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4423
    size_t used = get_eden_used();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4424
    size_t capacity = get_eden_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4425
    assert(used <= capacity, "Unexpected state of Eden");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4426
    if (used >  (capacity/100 * CMSScheduleRemarkEdenPenetration)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4427
      _abort_preclean = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4428
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4429
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4430
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4431
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4432
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4433
size_t CMSCollector::preclean_work(bool clean_refs, bool clean_survivor) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4434
  assert(_collectorState == Precleaning ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4435
         _collectorState == AbortablePreclean, "incorrect state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4436
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4437
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4438
  // Do one pass of scrubbing the discovered reference lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4439
  // to remove any reference objects with strongly-reachable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4440
  // referents.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4441
  if (clean_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4442
    ReferenceProcessor* rp = ref_processor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4443
    CMSPrecleanRefsYieldClosure yield_cl(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4444
    assert(rp->span().equals(_span), "Spans should be equal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4445
    CMSKeepAliveClosure keep_alive(this, _span, &_markBitMap,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4446
                                   &_markStack, &_revisitStack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4447
                                   true /* preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4448
    CMSDrainMarkingStackClosure complete_trace(this,
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  4449
                                   _span, &_markBitMap, &_markStack,
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  4450
                                   &keep_alive, true /* preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4451
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4452
    // We don't want this step to interfere with a young
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4453
    // collection because we don't want to take CPU
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4454
    // or memory bandwidth away from the young GC threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4455
    // (which may be as many as there are CPUs).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4456
    // Note that we don't need to protect ourselves from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4457
    // interference with mutators because they can't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4458
    // manipulate the discovered reference lists nor affect
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4459
    // the computed reachability of the referents, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4460
    // only properties manipulated by the precleaning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4461
    // of these reference lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4462
    stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4463
    CMSTokenSyncWithLocks x(true /* is cms thread */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4464
                            bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4465
    startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4466
    sample_eden();
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4467
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4468
    // The following will yield to allow foreground
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4469
    // collection to proceed promptly. XXX YSR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4470
    // The code in this method may need further
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4471
    // tweaking for better performance and some restructuring
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4472
    // for cleaner interfaces.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4473
    rp->preclean_discovered_references(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4474
          rp->is_alive_non_header(), &keep_alive, &complete_trace,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4475
          &yield_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4476
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4477
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4478
  if (clean_survivor) {  // preclean the active survivor space(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4479
    assert(_young_gen->kind() == Generation::DefNew ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4480
           _young_gen->kind() == Generation::ParNew ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4481
           _young_gen->kind() == Generation::ASParNew,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4482
         "incorrect type for cast");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4483
    DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4484
    PushAndMarkClosure pam_cl(this, _span, ref_processor(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4485
                             &_markBitMap, &_modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4486
                             &_markStack, &_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4487
                             true /* precleaning phase */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4488
    stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4489
    CMSTokenSyncWithLocks ts(true /* is cms thread */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4490
                             bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4491
    startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4492
    unsigned int before_count =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4493
      GenCollectedHeap::heap()->total_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4494
    SurvivorSpacePrecleanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4495
      sss_cl(this, _span, &_markBitMap, &_markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4496
             &pam_cl, before_count, CMSYield);
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4497
    DEBUG_ONLY(RememberKlassesChecker mx(CMSClassUnloadingEnabled);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4498
    dng->from()->object_iterate_careful(&sss_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4499
    dng->to()->object_iterate_careful(&sss_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4500
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4501
  MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4502
    mrias_cl(_span, ref_processor(), &_markBitMap, &_modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4503
             &_markStack, &_revisitStack, this, CMSYield,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4504
             true /* precleaning phase */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4505
  // CAUTION: The following closure has persistent state that may need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4506
  // be reset upon a decrease in the sequence of addresses it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4507
  // processes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4508
  ScanMarkedObjectsAgainCarefullyClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4509
    smoac_cl(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4510
      &_markBitMap, &_markStack, &_revisitStack, &mrias_cl, CMSYield);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4511
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4512
  // Preclean dirty cards in ModUnionTable and CardTable using
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4513
  // appropriate convergence criterion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4514
  // repeat CMSPrecleanIter times unless we find that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4515
  // we are losing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4516
  assert(CMSPrecleanIter < 10, "CMSPrecleanIter is too large");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4517
  assert(CMSPrecleanNumerator < CMSPrecleanDenominator,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4518
         "Bad convergence multiplier");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4519
  assert(CMSPrecleanThreshold >= 100,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4520
         "Unreasonably low CMSPrecleanThreshold");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4521
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4522
  size_t numIter, cumNumCards, lastNumCards, curNumCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4523
  for (numIter = 0, cumNumCards = lastNumCards = curNumCards = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4524
       numIter < CMSPrecleanIter;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4525
       numIter++, lastNumCards = curNumCards, cumNumCards += curNumCards) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4526
    curNumCards  = preclean_mod_union_table(_cmsGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4527
    if (CMSPermGenPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4528
      curNumCards  += preclean_mod_union_table(_permGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4529
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4530
    if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4531
      gclog_or_tty->print(" (modUnionTable: %d cards)", curNumCards);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4532
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4533
    // Either there are very few dirty cards, so re-mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4534
    // pause will be small anyway, or our pre-cleaning isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4535
    // that much faster than the rate at which cards are being
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4536
    // dirtied, so we might as well stop and re-mark since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4537
    // precleaning won't improve our re-mark time by much.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4538
    if (curNumCards <= CMSPrecleanThreshold ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4539
        (numIter > 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4540
         (curNumCards * CMSPrecleanDenominator >
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4541
         lastNumCards * CMSPrecleanNumerator))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4542
      numIter++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4543
      cumNumCards += curNumCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4544
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4545
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4546
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4547
  curNumCards = preclean_card_table(_cmsGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4548
  if (CMSPermGenPrecleaningEnabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4549
    curNumCards += preclean_card_table(_permGen, &smoac_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4550
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4551
  cumNumCards += curNumCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4552
  if (PrintGCDetails && PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4553
    gclog_or_tty->print_cr(" (cardTable: %d cards, re-scanned %d cards, %d iterations)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4554
                  curNumCards, cumNumCards, numIter);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4555
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4556
  return cumNumCards;   // as a measure of useful work done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4557
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4558
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4559
// PRECLEANING NOTES:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4560
// Precleaning involves:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4561
// . reading the bits of the modUnionTable and clearing the set bits.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4562
// . For the cards corresponding to the set bits, we scan the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4563
//   objects on those cards. This means we need the free_list_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4564
//   so that we can safely iterate over the CMS space when scanning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4565
//   for oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4566
// . When we scan the objects, we'll be both reading and setting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4567
//   marks in the marking bit map, so we'll need the marking bit map.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4568
// . For protecting _collector_state transitions, we take the CGC_lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4569
//   Note that any races in the reading of of card table entries by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4570
//   CMS thread on the one hand and the clearing of those entries by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4571
//   VM thread or the setting of those entries by the mutator threads on the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4572
//   other are quite benign. However, for efficiency it makes sense to keep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4573
//   the VM thread from racing with the CMS thread while the latter is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4574
//   dirty card info to the modUnionTable. We therefore also use the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4575
//   CGC_lock to protect the reading of the card table and the mod union
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4576
//   table by the CM thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4577
// . We run concurrently with mutator updates, so scanning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4578
//   needs to be done carefully  -- we should not try to scan
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4579
//   potentially uninitialized objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4580
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4581
// Locking strategy: While holding the CGC_lock, we scan over and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4582
// reset a maximal dirty range of the mod union / card tables, then lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4583
// the free_list_lock and bitmap lock to do a full marking, then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4584
// release these locks; and repeat the cycle. This allows for a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4585
// certain amount of fairness in the sharing of these locks between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4586
// the CMS collector on the one hand, and the VM thread and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4587
// mutators on the other.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4588
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4589
// NOTE: preclean_mod_union_table() and preclean_card_table()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4590
// further below are largely identical; if you need to modify
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4591
// one of these methods, please check the other method too.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4592
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4593
size_t CMSCollector::preclean_mod_union_table(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4594
  ConcurrentMarkSweepGeneration* gen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4595
  ScanMarkedObjectsAgainCarefullyClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4596
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4597
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4598
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4599
  // Turn off checking for this method but turn it back on
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4600
  // selectively.  There are yield points in this method
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4601
  // but it is difficult to turn the checking off just around
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4602
  // the yield points.  It is simpler to selectively turn
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4603
  // it on.
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4604
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4605
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4606
  // strategy: starting with the first card, accumulate contiguous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4607
  // ranges of dirty cards; clear these cards, then scan the region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4608
  // covered by these cards.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4609
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4610
  // Since all of the MUT is committed ahead, we can just use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4611
  // that, in case the generations expand while we are precleaning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4612
  // It might also be fine to just use the committed part of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4613
  // generation, but we might potentially miss cards when the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4614
  // generation is rapidly expanding while we are in the midst
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4615
  // of precleaning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4616
  HeapWord* startAddr = gen->reserved().start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4617
  HeapWord* endAddr   = gen->reserved().end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4618
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4619
  cl->setFreelistLock(gen->freelistLock());   // needed for yielding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4620
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4621
  size_t numDirtyCards, cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4622
  HeapWord *nextAddr, *lastAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4623
  for (cumNumDirtyCards = numDirtyCards = 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4624
       nextAddr = lastAddr = startAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4625
       nextAddr < endAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4626
       nextAddr = lastAddr, cumNumDirtyCards += numDirtyCards) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4627
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4628
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4629
    HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4630
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4631
    MemRegion dirtyRegion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4632
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4633
      stopTimer();
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4634
      // Potential yield point
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4635
      CMSTokenSync ts(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4636
      startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4637
      sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4638
      // Get dirty region starting at nextOffset (inclusive),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4639
      // simultaneously clearing it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4640
      dirtyRegion =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4641
        _modUnionTable.getAndClearMarkedRegion(nextAddr, endAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4642
      assert(dirtyRegion.start() >= nextAddr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4643
             "returned region inconsistent?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4644
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4645
    // Remember where the next search should begin.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4646
    // The returned region (if non-empty) is a right open interval,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4647
    // so lastOffset is obtained from the right end of that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4648
    // interval.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4649
    lastAddr = dirtyRegion.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4650
    // Should do something more transparent and less hacky XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4651
    numDirtyCards =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4652
      _modUnionTable.heapWordDiffToOffsetDiff(dirtyRegion.word_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4653
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4654
    // We'll scan the cards in the dirty region (with periodic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4655
    // yields for foreground GC as needed).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4656
    if (!dirtyRegion.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4657
      assert(numDirtyCards > 0, "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4658
      HeapWord* stop_point = NULL;
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4659
      stopTimer();
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4660
      // Potential yield point
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4661
      CMSTokenSyncWithLocks ts(true, gen->freelistLock(),
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4662
                               bitMapLock());
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  4663
      startTimer();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4664
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4665
        verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4666
        verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4667
        sample_eden();
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4668
        DEBUG_ONLY(RememberKlassesChecker mx(CMSClassUnloadingEnabled);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4669
        stop_point =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4670
          gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4671
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4672
      if (stop_point != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4673
        // The careful iteration stopped early either because it found an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4674
        // uninitialized object, or because we were in the midst of an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4675
        // "abortable preclean", which should now be aborted. Redirty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4676
        // the bits corresponding to the partially-scanned or unscanned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4677
        // cards. We'll either restart at the next block boundary or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4678
        // abort the preclean.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4679
        assert((CMSPermGenPrecleaningEnabled && (gen == _permGen)) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4680
               (_collectorState == AbortablePreclean && should_abort_preclean()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4681
               "Unparsable objects should only be in perm gen.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4682
        _modUnionTable.mark_range(MemRegion(stop_point, dirtyRegion.end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4683
        if (should_abort_preclean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4684
          break; // out of preclean loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4685
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4686
          // Compute the next address at which preclean should pick up;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4687
          // might need bitMapLock in order to read P-bits.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4688
          lastAddr = next_card_start_after_block(stop_point);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4689
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4690
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4691
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4692
      assert(lastAddr == endAddr, "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4693
      assert(numDirtyCards == 0, "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4694
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4695
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4696
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4697
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4698
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4699
  return cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4700
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4701
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4702
// NOTE: preclean_mod_union_table() above and preclean_card_table()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4703
// below are largely identical; if you need to modify
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4704
// one of these methods, please check the other method too.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4705
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4706
size_t CMSCollector::preclean_card_table(ConcurrentMarkSweepGeneration* gen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4707
  ScanMarkedObjectsAgainCarefullyClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4708
  // strategy: it's similar to precleamModUnionTable above, in that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4709
  // we accumulate contiguous ranges of dirty cards, mark these cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4710
  // precleaned, then scan the region covered by these cards.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4711
  HeapWord* endAddr   = (HeapWord*)(gen->_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4712
  HeapWord* startAddr = (HeapWord*)(gen->_virtual_space.low());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4713
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4714
  cl->setFreelistLock(gen->freelistLock());   // needed for yielding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4715
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4716
  size_t numDirtyCards, cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4717
  HeapWord *lastAddr, *nextAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4718
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4719
  for (cumNumDirtyCards = numDirtyCards = 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4720
       nextAddr = lastAddr = startAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4721
       nextAddr < endAddr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4722
       nextAddr = lastAddr, cumNumDirtyCards += numDirtyCards) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4723
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4724
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4725
    HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4726
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4727
    MemRegion dirtyRegion;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4728
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4729
      // See comments in "Precleaning notes" above on why we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4730
      // do this locking. XXX Could the locking overheads be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4731
      // too high when dirty cards are sparse? [I don't think so.]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4732
      stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4733
      CMSTokenSync x(true); // is cms thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4734
      startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4735
      sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4736
      // Get and clear dirty region from card table
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4737
      dirtyRegion = _ct->ct_bs()->dirty_card_range_after_reset(
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4738
                                    MemRegion(nextAddr, endAddr),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4739
                                    true,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4740
                                    CardTableModRefBS::precleaned_card_val());
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  4741
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4742
      assert(dirtyRegion.start() >= nextAddr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4743
             "returned region inconsistent?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4744
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4745
    lastAddr = dirtyRegion.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4746
    numDirtyCards =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4747
      dirtyRegion.word_size()/CardTableModRefBS::card_size_in_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4748
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4749
    if (!dirtyRegion.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4750
      stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4751
      CMSTokenSyncWithLocks ts(true, gen->freelistLock(), bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4752
      startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4753
      sample_eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4754
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4755
      verify_overflow_empty();
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4756
      DEBUG_ONLY(RememberKlassesChecker mx(CMSClassUnloadingEnabled);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4757
      HeapWord* stop_point =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4758
        gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4759
      if (stop_point != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4760
        // The careful iteration stopped early because it found an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4761
        // uninitialized object.  Redirty the bits corresponding to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4762
        // partially-scanned or unscanned cards, and start again at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4763
        // next block boundary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4764
        assert(CMSPermGenPrecleaningEnabled ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4765
               (_collectorState == AbortablePreclean && should_abort_preclean()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4766
               "Unparsable objects should only be in perm gen.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4767
        _ct->ct_bs()->invalidate(MemRegion(stop_point, dirtyRegion.end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4768
        if (should_abort_preclean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4769
          break; // out of preclean loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4770
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4771
          // Compute the next address at which preclean should pick up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4772
          lastAddr = next_card_start_after_block(stop_point);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4773
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4774
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4775
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4776
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4777
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4778
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4779
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4780
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4781
  return cumNumDirtyCards;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4782
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4784
void CMSCollector::checkpointRootsFinal(bool asynch,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4785
  bool clear_all_soft_refs, bool init_mark_was_synchronous) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4786
  assert(_collectorState == FinalMarking, "incorrect state transition?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4787
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4788
  // world is stopped at this checkpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4789
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4790
         "world should be stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4791
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4792
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4793
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4794
  SpecializationStats::clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4795
  if (PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4796
    gclog_or_tty->print("[YG occupancy: "SIZE_FORMAT" K ("SIZE_FORMAT" K)]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4797
                        _young_gen->used() / K,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4798
                        _young_gen->capacity() / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4799
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4800
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4801
    if (CMSScavengeBeforeRemark) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4802
      GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4803
      // Temporarily set flag to false, GCH->do_collection will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4804
      // expect it to be false and set to true
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4805
      FlagSetting fl(gch->_is_gc_active, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4806
      NOT_PRODUCT(TraceTime t("Scavenge-Before-Remark",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4807
        PrintGCDetails && Verbose, true, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4808
      int level = _cmsGen->level() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4809
      if (level >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4810
        gch->do_collection(true,        // full (i.e. force, see below)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4811
                           false,       // !clear_all_soft_refs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4812
                           0,           // size
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4813
                           false,       // is_tlab
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4814
                           level        // max_level
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4815
                          );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4816
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4817
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4818
    FreelistLocker x(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4819
    MutexLockerEx y(bitMapLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4820
                    Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4821
    assert(!init_mark_was_synchronous, "but that's impossible!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4822
    checkpointRootsFinalWork(asynch, clear_all_soft_refs, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4823
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4824
    // already have all the locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4825
    checkpointRootsFinalWork(asynch, clear_all_soft_refs,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4826
                             init_mark_was_synchronous);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4827
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4828
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4829
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4830
  SpecializationStats::print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4831
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4832
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4833
void CMSCollector::checkpointRootsFinalWork(bool asynch,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4834
  bool clear_all_soft_refs, bool init_mark_was_synchronous) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4835
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4836
  NOT_PRODUCT(TraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4837
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4838
  assert(haveFreelistLocks(), "must have free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4839
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4840
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4841
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4842
    size_policy()->checkpoint_roots_final_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4843
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4844
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4845
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4846
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4847
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4848
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4849
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  4850
  if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4851
    CodeCache::gc_prologue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4852
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4853
  assert(haveFreelistLocks(), "must have free list locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4854
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4855
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4856
  DEBUG_ONLY(RememberKlassesChecker fmx(CMSClassUnloadingEnabled);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4857
  if (!init_mark_was_synchronous) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4858
    // We might assume that we need not fill TLAB's when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4859
    // CMSScavengeBeforeRemark is set, because we may have just done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4860
    // a scavenge which would have filled all TLAB's -- and besides
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4861
    // Eden would be empty. This however may not always be the case --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4862
    // for instance although we asked for a scavenge, it may not have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4863
    // happened because of a JNI critical section. We probably need
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4864
    // a policy for deciding whether we can in that case wait until
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4865
    // the critical section releases and then do the remark following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4866
    // the scavenge, and skip it here. In the absence of that policy,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4867
    // or of an indication of whether the scavenge did indeed occur,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4868
    // we cannot rely on TLAB's having been filled and must do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4869
    // so here just in case a scavenge did not happen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4870
    gch->ensure_parsability(false);  // fill TLAB's, but no need to retire them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4871
    // Update the saved marks which may affect the root scans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4872
    gch->save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4873
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4874
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4875
      COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4876
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4877
      // Note on the role of the mod union table:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4878
      // Since the marker in "markFromRoots" marks concurrently with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4879
      // mutators, it is possible for some reachable objects not to have been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4880
      // scanned. For instance, an only reference to an object A was
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4881
      // placed in object B after the marker scanned B. Unless B is rescanned,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4882
      // A would be collected. Such updates to references in marked objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4883
      // are detected via the mod union table which is the set of all cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4884
      // dirtied since the first checkpoint in this GC cycle and prior to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4885
      // the most recent young generation GC, minus those cleaned up by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4886
      // concurrent precleaning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4887
      if (CMSParallelRemarkEnabled && ParallelGCThreads > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4888
        TraceTime t("Rescan (parallel) ", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4889
        do_remark_parallel();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4890
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4891
        TraceTime t("Rescan (non-parallel) ", PrintGCDetails, false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4892
                    gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4893
        do_remark_non_parallel();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4894
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4895
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4896
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4897
    assert(!asynch, "Can't have init_mark_was_synchronous in asynch mode");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4898
    // The initial mark was stop-world, so there's no rescanning to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4899
    // do; go straight on to the next step below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4900
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4901
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4902
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4903
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4904
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4905
    NOT_PRODUCT(TraceTime ts("refProcessingWork", PrintGCDetails, false, gclog_or_tty);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4906
    refProcessingWork(asynch, clear_all_soft_refs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4907
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4908
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4909
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4910
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  4911
  if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4912
    CodeCache::gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4913
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4914
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4915
  // If we encountered any (marking stack / work queue) overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4916
  // events during the current CMS cycle, take appropriate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4917
  // remedial measures, where possible, so as to try and avoid
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4918
  // recurrence of that condition.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4919
  assert(_markStack.isEmpty(), "No grey objects");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4920
  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
  4921
                     _ser_kac_ovflw        + _ser_kac_preclean_ovflw;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4922
  if (ser_ovflw > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4923
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4924
      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
  4925
        "(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
  4926
        ", kac_preclean="SIZE_FORMAT")",
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4927
        _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
  4928
        _ser_kac_ovflw, _ser_kac_preclean_ovflw);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4929
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4930
    _markStack.expand();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4931
    _ser_pmc_remark_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4932
    _ser_pmc_preclean_ovflw = 0;
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  4933
    _ser_kac_preclean_ovflw = 0;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4934
    _ser_kac_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4935
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4936
  if (_par_pmc_remark_ovflw > 0 || _par_kac_ovflw > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4937
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4938
      gclog_or_tty->print_cr("Work queue overflow (benign) "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4939
        "(pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT")",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4940
        _par_pmc_remark_ovflw, _par_kac_ovflw);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4941
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4942
    _par_pmc_remark_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4943
    _par_kac_ovflw = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4944
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4945
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4946
     if (_markStack._hit_limit > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4947
       gclog_or_tty->print_cr(" (benign) Hit max stack size limit ("SIZE_FORMAT")",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4948
                              _markStack._hit_limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4949
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4950
     if (_markStack._failed_double > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4951
       gclog_or_tty->print_cr(" (benign) Failed stack doubling ("SIZE_FORMAT"),"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4952
                              " current capacity "SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4953
                              _markStack._failed_double,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4954
                              _markStack.capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4955
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4956
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4957
  _markStack._hit_limit = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4958
  _markStack._failed_double = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4959
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4960
  // Check that all the klasses have been checked
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4961
  assert(_revisitStack.isEmpty(), "Not all klasses revisited");
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  4962
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4963
  if ((VerifyAfterGC || VerifyDuringGC) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4964
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4965
    verify_after_remark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4966
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4967
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4968
  // Change under the freelistLocks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4969
  _collectorState = Sweeping;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4970
  // Call isAllClear() under bitMapLock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4971
  assert(_modUnionTable.isAllClear(), "Should be clear by end of the"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4972
    " final marking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4973
  if (UseAdaptiveSizePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4974
    size_policy()->checkpoint_roots_final_end(gch->gc_cause());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4975
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4976
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4977
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4978
// Parallel remark task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4979
class CMSParRemarkTask: public AbstractGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4980
  CMSCollector* _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4981
  WorkGang*     _workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4982
  int           _n_workers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4983
  CompactibleFreeListSpace* _cms_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4984
  CompactibleFreeListSpace* _perm_space;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4985
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4986
  // The per-thread work queues, available here for stealing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4987
  OopTaskQueueSet*       _task_queues;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4988
  ParallelTaskTerminator _term;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4989
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4990
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4991
  CMSParRemarkTask(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4992
                   CompactibleFreeListSpace* cms_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4993
                   CompactibleFreeListSpace* perm_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4994
                   int n_workers, WorkGang* workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4995
                   OopTaskQueueSet* task_queues):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4996
    AbstractGangTask("Rescan roots and grey objects in parallel"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4997
    _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4998
    _cms_space(cms_space), _perm_space(perm_space),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4999
    _n_workers(n_workers),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5000
    _workers(workers),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5001
    _task_queues(task_queues),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5002
    _term(workers->total_workers(), task_queues) { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5003
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5004
  OopTaskQueueSet* task_queues() { return _task_queues; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5005
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5006
  OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5007
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5008
  ParallelTaskTerminator* terminator() { return &_term; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5009
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5010
  void work(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5011
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5012
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5013
  // Work method in support of parallel rescan ... of young gen spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5014
  void do_young_space_rescan(int i, Par_MarkRefsIntoAndScanClosure* cl,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5015
                             ContiguousSpace* space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5016
                             HeapWord** chunk_array, size_t chunk_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5018
  // ... of  dirty cards in old space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5019
  void do_dirty_card_rescan_tasks(CompactibleFreeListSpace* sp, int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5020
                                  Par_MarkRefsIntoAndScanClosure* cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5021
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5022
  // ... work stealing for the above
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5023
  void do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl, int* seed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5024
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5025
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5026
void CMSParRemarkTask::work(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5027
  elapsedTimer _timer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5028
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5029
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5030
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5031
  // ---------- rescan from roots --------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5032
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5033
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5034
  Par_MarkRefsIntoAndScanClosure par_mrias_cl(_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5035
    _collector->_span, _collector->ref_processor(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5036
    &(_collector->_markBitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5037
    work_queue(i), &(_collector->_revisitStack));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5038
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5039
  // Rescan young gen roots first since these are likely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5040
  // coarsely partitioned and may, on that account, constitute
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5041
  // the critical path; thus, it's best to start off that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5042
  // work first.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5043
  // ---------- young gen roots --------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5044
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5045
    DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5046
    EdenSpace* eden_space = dng->eden();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5047
    ContiguousSpace* from_space = dng->from();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5048
    ContiguousSpace* to_space   = dng->to();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5049
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5050
    HeapWord** eca = _collector->_eden_chunk_array;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5051
    size_t     ect = _collector->_eden_chunk_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5052
    HeapWord** sca = _collector->_survivor_chunk_array;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5053
    size_t     sct = _collector->_survivor_chunk_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5054
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5055
    assert(ect <= _collector->_eden_chunk_capacity, "out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5056
    assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5057
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5058
    do_young_space_rescan(i, &par_mrias_cl, to_space, NULL, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5059
    do_young_space_rescan(i, &par_mrias_cl, from_space, sca, sct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5060
    do_young_space_rescan(i, &par_mrias_cl, eden_space, eca, ect);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5061
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5062
    _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5063
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5064
      gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5065
        "Finished young gen rescan work in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5066
        i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5067
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5068
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5069
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5070
  // ---------- remaining roots --------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5071
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5072
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5073
  gch->gen_process_strong_roots(_collector->_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5074
                                false,     // yg was scanned above
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5075
                                false,     // this is parallel code
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5076
                                true,      // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5077
                                SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5078
                                &par_mrias_cl,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5079
                                true,   // walk all of code cache if (so & SO_CodeCache)
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5080
                                NULL);
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5081
  assert(_collector->should_unload_classes()
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5082
         || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_CodeCache),
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5083
         "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5084
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5085
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5086
    gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5087
      "Finished remaining root rescan work in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5088
      i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5089
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5090
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5091
  // ---------- rescan dirty cards ------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5092
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5093
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5094
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5095
  // Do the rescan tasks for each of the two spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5096
  // (cms_space and perm_space) in turn.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5097
  do_dirty_card_rescan_tasks(_cms_space, i, &par_mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5098
  do_dirty_card_rescan_tasks(_perm_space, i, &par_mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5099
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5100
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5101
    gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5102
      "Finished dirty card rescan work in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5103
      i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5104
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5105
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5106
  // ---------- steal work from other threads ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5107
  // ---------- ... and drain overflow list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5108
  _timer.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5109
  _timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5110
  do_work_steal(i, &par_mrias_cl, _collector->hash_seed(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5111
  _timer.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5112
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5113
    gclog_or_tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5114
      "Finished work stealing in %dth thread: %3.3f sec",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5115
      i, _timer.seconds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5116
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5117
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5118
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5119
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5120
CMSParRemarkTask::do_young_space_rescan(int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5121
  Par_MarkRefsIntoAndScanClosure* cl, ContiguousSpace* space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5122
  HeapWord** chunk_array, size_t chunk_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5123
  // Until all tasks completed:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5124
  // . claim an unclaimed task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5125
  // . compute region boundaries corresponding to task claimed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5126
  //   using chunk_array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5127
  // . par_oop_iterate(cl) over that region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5128
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5129
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5130
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5131
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5132
  SequentialSubTasksDone* pst = space->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5133
  assert(pst->valid(), "Uninitialized use?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5134
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5135
  int nth_task = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5136
  int n_tasks  = pst->n_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5137
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5138
  HeapWord *start, *end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5139
  while (!pst->is_task_claimed(/* reference */ nth_task)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5140
    // We claimed task # nth_task; compute its boundaries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5141
    if (chunk_top == 0) {  // no samples were taken
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5142
      assert(nth_task == 0 && n_tasks == 1, "Can have only 1 EdenSpace task");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5143
      start = space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5144
      end   = space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5145
    } else if (nth_task == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5146
      start = space->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5147
      end   = chunk_array[nth_task];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5148
    } else if (nth_task < (jint)chunk_top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5149
      assert(nth_task >= 1, "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5150
      start = chunk_array[nth_task - 1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5151
      end   = chunk_array[nth_task];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5152
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5153
      assert(nth_task == (jint)chunk_top, "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5154
      start = chunk_array[chunk_top - 1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5155
      end   = space->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5156
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5157
    MemRegion mr(start, end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5158
    // Verify that mr is in space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5159
    assert(mr.is_empty() || space->used_region().contains(mr),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5160
           "Should be in space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5161
    // Verify that "start" is an object boundary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5162
    assert(mr.is_empty() || oop(mr.start())->is_oop(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5163
           "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5164
    space->par_oop_iterate(mr, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5165
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5166
  pst->all_tasks_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5167
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5168
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5169
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5170
CMSParRemarkTask::do_dirty_card_rescan_tasks(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5171
  CompactibleFreeListSpace* sp, int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5172
  Par_MarkRefsIntoAndScanClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5173
  // Until all tasks completed:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5174
  // . claim an unclaimed task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5175
  // . compute region boundaries corresponding to task claimed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5176
  // . transfer dirty bits ct->mut for that region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5177
  // . apply rescanclosure to dirty mut bits for that region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5179
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5180
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5181
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5182
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5183
  ModUnionClosure modUnionClosure(&(_collector->_modUnionTable));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5184
  // CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! CAUTION!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5185
  // CAUTION: This closure has state that persists across calls to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5186
  // the work method dirty_range_iterate_clear() in that it has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5187
  // imbedded in it a (subtype of) UpwardsObjectClosure. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5188
  // use of that state in the imbedded UpwardsObjectClosure instance
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5189
  // assumes that the cards are always iterated (even if in parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5190
  // by several threads) in monotonically increasing order per each
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5191
  // thread. This is true of the implementation below which picks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5192
  // card ranges (chunks) in monotonically increasing order globally
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5193
  // and, a-fortiori, in monotonically increasing order per thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5194
  // (the latter order being a subsequence of the former).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5195
  // If the work code below is ever reorganized into a more chaotic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5196
  // work-partitioning form than the current "sequential tasks"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5197
  // paradigm, the use of that persistent state will have to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5198
  // revisited and modified appropriately. See also related
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5199
  // bug 4756801 work on which should examine this code to make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5200
  // sure that the changes there do not run counter to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5201
  // assumptions made here and necessary for correctness and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5202
  // efficiency. Note also that this code might yield inefficient
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5203
  // behaviour in the case of very large objects that span one or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5204
  // more work chunks. Such objects would potentially be scanned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5205
  // several times redundantly. Work on 4756801 should try and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5206
  // address that performance anomaly if at all possible. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5207
  MemRegion  full_span  = _collector->_span;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5208
  CMSBitMap* bm    = &(_collector->_markBitMap);     // shared
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5209
  CMSMarkStack* rs = &(_collector->_revisitStack);   // shared
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5210
  MarkFromDirtyCardsClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5211
    greyRescanClosure(_collector, full_span, // entire span of interest
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5212
                      sp, bm, work_q, rs, cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5213
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5214
  SequentialSubTasksDone* pst = sp->conc_par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5215
  assert(pst->valid(), "Uninitialized use?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5216
  int nth_task = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5217
  const int alignment = CardTableModRefBS::card_size * BitsPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5218
  MemRegion span = sp->used_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5219
  HeapWord* start_addr = span.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5220
  HeapWord* end_addr = (HeapWord*)round_to((intptr_t)span.end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5221
                                           alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5222
  const size_t chunk_size = sp->rescan_task_size(); // in HeapWord units
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5223
  assert((HeapWord*)round_to((intptr_t)start_addr, alignment) ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5224
         start_addr, "Check alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5225
  assert((size_t)round_to((intptr_t)chunk_size, alignment) ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5226
         chunk_size, "Check alignment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5227
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5228
  while (!pst->is_task_claimed(/* reference */ nth_task)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5229
    // Having claimed the nth_task, compute corresponding mem-region,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5230
    // which is a-fortiori aligned correctly (i.e. at a MUT bopundary).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5231
    // The alignment restriction ensures that we do not need any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5232
    // synchronization with other gang-workers while setting or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5233
    // clearing bits in thus chunk of the MUT.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5234
    MemRegion this_span = MemRegion(start_addr + nth_task*chunk_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5235
                                    start_addr + (nth_task+1)*chunk_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5236
    // The last chunk's end might be way beyond end of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5237
    // used region. In that case pull back appropriately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5238
    if (this_span.end() > end_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5239
      this_span.set_end(end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5240
      assert(!this_span.is_empty(), "Program logic (calculation of n_tasks)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5241
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5242
    // Iterate over the dirty cards covering this chunk, marking them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5243
    // precleaned, and setting the corresponding bits in the mod union
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5244
    // table. Since we have been careful to partition at Card and MUT-word
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5245
    // boundaries no synchronization is needed between parallel threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5246
    _collector->_ct->ct_bs()->dirty_card_iterate(this_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5247
                                                 &modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5248
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5249
    // Having transferred these marks into the modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5250
    // rescan the marked objects on the dirty cards in the modUnionTable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5251
    // Even if this is at a synchronous collection, the initial marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5252
    // may have been done during an asynchronous collection so there
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5253
    // may be dirty bits in the mod-union table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5254
    _collector->_modUnionTable.dirty_range_iterate_clear(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5255
                  this_span, &greyRescanClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5256
    _collector->_modUnionTable.verifyNoOneBitsInRange(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5257
                                 this_span.start(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5258
                                 this_span.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5259
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5260
  pst->all_tasks_completed();  // declare that i am done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5261
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5262
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5263
// . see if we can share work_queues with ParNew? XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5264
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5265
CMSParRemarkTask::do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5266
                                int* seed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5267
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5268
  NOT_PRODUCT(int num_steals = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5269
  oop obj_to_scan;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5270
  CMSBitMap* bm = &(_collector->_markBitMap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5271
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5272
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5273
    // Completely finish any left over work from (an) earlier round(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5274
    cl->trim_queue(0);
2346
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  5275
    size_t num_from_overflow_list = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  5276
                                         (size_t)ParGCDesiredObjsFromOverflowList);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5277
    // Now check if there's any work in the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5278
    if (_collector->par_take_from_overflow_list(num_from_overflow_list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5279
                                                work_q)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5280
      // found something in global overflow list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5281
      // not yet ready to go stealing work from others.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5282
      // We'd like to assert(work_q->size() != 0, ...)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5283
      // because we just took work from the overflow list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5284
      // but of course we can't since all of that could have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5285
      // been already stolen from us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5286
      // "He giveth and He taketh away."
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5287
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5288
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5289
    // Verify that we have no work before we resort to stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5290
    assert(work_q->size() == 0, "Have work, shouldn't steal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5291
    // Try to steal from other queues that have work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5292
    if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5293
      NOT_PRODUCT(num_steals++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5294
      assert(obj_to_scan->is_oop(), "Oops, not an oop!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5295
      assert(bm->isMarked((HeapWord*)obj_to_scan), "Stole an unmarked oop?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5296
      // Do scanning work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5297
      obj_to_scan->oop_iterate(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5298
      // Loop around, finish this work, and try to steal some more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5299
    } else if (terminator()->offer_termination()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5300
        break;  // nirvana from the infinite cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5301
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5302
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5303
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5304
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5305
      gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5306
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5307
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5308
  assert(work_q->size() == 0 && _collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5309
         "Else our work is not yet done");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5310
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5311
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5312
// Return a thread-local PLAB recording array, as appropriate.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5313
void* CMSCollector::get_data_recorder(int thr_num) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5314
  if (_survivor_plab_array != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5315
      (CMSPLABRecordAlways ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5316
       (_collectorState > Marking && _collectorState < FinalMarking))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5317
    assert(thr_num < (int)ParallelGCThreads, "thr_num is out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5318
    ChunkArray* ca = &_survivor_plab_array[thr_num];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5319
    ca->reset();   // clear it so that fresh data is recorded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5320
    return (void*) ca;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5321
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5322
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5323
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5324
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5325
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5326
// Reset all the thread-local PLAB recording arrays
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5327
void CMSCollector::reset_survivor_plab_arrays() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5328
  for (uint i = 0; i < ParallelGCThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5329
    _survivor_plab_array[i].reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5330
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5331
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5332
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5333
// Merge the per-thread plab arrays into the global survivor chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5334
// array which will provide the partitioning of the survivor space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5335
// for CMS rescan.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5336
void CMSCollector::merge_survivor_plab_arrays(ContiguousSpace* surv) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5337
  assert(_survivor_plab_array  != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5338
  assert(_survivor_chunk_array != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5339
  assert(_collectorState == FinalMarking, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5340
  for (uint j = 0; j < ParallelGCThreads; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5341
    _cursor[j] = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5342
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5343
  HeapWord* top = surv->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5344
  size_t i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5345
  for (i = 0; i < _survivor_chunk_capacity; i++) {  // all sca entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5346
    HeapWord* min_val = top;          // Higher than any PLAB address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5347
    uint      min_tid = 0;            // position of min_val this round
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5348
    for (uint j = 0; j < ParallelGCThreads; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5349
      ChunkArray* cur_sca = &_survivor_plab_array[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5350
      if (_cursor[j] == cur_sca->end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5351
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5352
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5353
      assert(_cursor[j] < cur_sca->end(), "ctl pt invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5354
      HeapWord* cur_val = cur_sca->nth(_cursor[j]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5355
      assert(surv->used_region().contains(cur_val), "Out of bounds value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5356
      if (cur_val < min_val) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5357
        min_tid = j;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5358
        min_val = cur_val;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5359
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5360
        assert(cur_val < top, "All recorded addresses should be less");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5361
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5362
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5363
    // At this point min_val and min_tid are respectively
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5364
    // the least address in _survivor_plab_array[j]->nth(_cursor[j])
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5365
    // and the thread (j) that witnesses that address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5366
    // We record this address in the _survivor_chunk_array[i]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5367
    // and increment _cursor[min_tid] prior to the next round i.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5368
    if (min_val == top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5369
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5370
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5371
    _survivor_chunk_array[i] = min_val;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5372
    _cursor[min_tid]++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5373
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5374
  // We are all done; record the size of the _survivor_chunk_array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5375
  _survivor_chunk_index = i; // exclusive: [0, i)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5376
  if (PrintCMSStatistics > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5377
    gclog_or_tty->print(" (Survivor:" SIZE_FORMAT "chunks) ", i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5378
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5379
  // Verify that we used up all the recorded entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5380
  #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5381
    size_t total = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5382
    for (uint j = 0; j < ParallelGCThreads; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5383
      assert(_cursor[j] == _survivor_plab_array[j].end(), "Ctl pt invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5384
      total += _cursor[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5385
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5386
    assert(total == _survivor_chunk_index, "Ctl Pt Invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5387
    // Check that the merged array is in sorted order
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5388
    if (total > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5389
      for (size_t i = 0; i < total - 1; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5390
        if (PrintCMSStatistics > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5391
          gclog_or_tty->print(" (chunk" SIZE_FORMAT ":" INTPTR_FORMAT ") ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5392
                              i, _survivor_chunk_array[i]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5393
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5394
        assert(_survivor_chunk_array[i] < _survivor_chunk_array[i+1],
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5395
               "Not sorted");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5396
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5397
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5398
  #endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5399
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5400
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5401
// Set up the space's par_seq_tasks structure for work claiming
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5402
// for parallel rescan of young gen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5403
// See ParRescanTask where this is currently used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5404
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5405
CMSCollector::
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5406
initialize_sequential_subtasks_for_young_gen_rescan(int n_threads) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5407
  assert(n_threads > 0, "Unexpected n_threads argument");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5408
  DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5409
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5410
  // Eden space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5411
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5412
    SequentialSubTasksDone* pst = dng->eden()->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5413
    assert(!pst->valid(), "Clobbering existing data?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5414
    // Each valid entry in [0, _eden_chunk_index) represents a task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5415
    size_t n_tasks = _eden_chunk_index + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5416
    assert(n_tasks == 1 || _eden_chunk_array != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5417
    pst->set_par_threads(n_threads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5418
    pst->set_n_tasks((int)n_tasks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5419
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5420
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5421
  // Merge the survivor plab arrays into _survivor_chunk_array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5422
  if (_survivor_plab_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5423
    merge_survivor_plab_arrays(dng->from());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5424
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5425
    assert(_survivor_chunk_index == 0, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5426
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5427
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5428
  // To space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5429
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5430
    SequentialSubTasksDone* pst = dng->to()->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5431
    assert(!pst->valid(), "Clobbering existing data?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5432
    pst->set_par_threads(n_threads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5433
    pst->set_n_tasks(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5434
    assert(pst->valid(), "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5435
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5436
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5437
  // From space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5438
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5439
    SequentialSubTasksDone* pst = dng->from()->par_seq_tasks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5440
    assert(!pst->valid(), "Clobbering existing data?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5441
    size_t n_tasks = _survivor_chunk_index + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5442
    assert(n_tasks == 1 || _survivor_chunk_array != NULL, "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5443
    pst->set_par_threads(n_threads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5444
    pst->set_n_tasks((int)n_tasks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5445
    assert(pst->valid(), "Error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5446
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5447
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5448
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5449
// Parallel version of remark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5450
void CMSCollector::do_remark_parallel() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5451
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5452
  WorkGang* workers = gch->workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5453
  assert(workers != NULL, "Need parallel worker threads.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5454
  int n_workers = workers->total_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5455
  CompactibleFreeListSpace* cms_space  = _cmsGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5456
  CompactibleFreeListSpace* perm_space = _permGen->cmsSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5457
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5458
  CMSParRemarkTask tsk(this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5459
    cms_space, perm_space,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5460
    n_workers, workers, task_queues());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5461
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5462
  // Set up for parallel process_strong_roots work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5463
  gch->set_par_threads(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5464
  // We won't be iterating over the cards in the card table updating
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5465
  // the younger_gen cards, so we shouldn't call the following else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5466
  // the verification code as well as subsequent younger_refs_iterate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5467
  // code would get confused. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5468
  // gch->rem_set()->prepare_for_younger_refs_iterate(true); // parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5469
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5470
  // The young gen rescan work will not be done as part of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5471
  // process_strong_roots (which currently doesn't knw how to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5472
  // parallelize such a scan), but rather will be broken up into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5473
  // a set of parallel tasks (via the sampling that the [abortable]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5474
  // preclean phase did of EdenSpace, plus the [two] tasks of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5475
  // scanning the [two] survivor spaces. Further fine-grain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5476
  // parallelization of the scanning of the survivor spaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5477
  // themselves, and of precleaning of the younger gen itself
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5478
  // is deferred to the future.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5479
  initialize_sequential_subtasks_for_young_gen_rescan(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5480
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5481
  // The dirty card rescan work is broken up into a "sequence"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5482
  // of parallel tasks (per constituent space) that are dynamically
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5483
  // claimed by the parallel threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5484
  cms_space->initialize_sequential_subtasks_for_rescan(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5485
  perm_space->initialize_sequential_subtasks_for_rescan(n_workers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5486
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5487
  // It turns out that even when we're using 1 thread, doing the work in a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5488
  // separate thread causes wide variance in run times.  We can't help this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5489
  // in the multi-threaded case, but we special-case n=1 here to get
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5490
  // repeatable measurements of the 1-thread overhead of the parallel code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5491
  if (n_workers > 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5492
    // Make refs discovery MT-safe
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5493
    ReferenceProcessorMTMutator mt(ref_processor(), true);
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5494
    GenCollectedHeap::StrongRootsScope srs(gch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5495
    workers->run_task(&tsk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5496
  } else {
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5497
    GenCollectedHeap::StrongRootsScope srs(gch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5498
    tsk.work(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5499
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5500
  gch->set_par_threads(0);  // 0 ==> non-parallel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5501
  // restore, single-threaded for now, any preserved marks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5502
  // as a result of work_q overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5503
  restore_preserved_marks_if_any();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5504
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5505
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5506
// Non-parallel version of remark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5507
void CMSCollector::do_remark_non_parallel() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5508
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5509
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5510
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5511
  MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5512
    mrias_cl(_span, ref_processor(), &_markBitMap, &_modUnionTable,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5513
             &_markStack, &_revisitStack, this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5514
             false /* should_yield */, false /* not precleaning */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5515
  MarkFromDirtyCardsClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5516
    markFromDirtyCardsClosure(this, _span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5517
                              NULL,  // space is set further below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5518
                              &_markBitMap, &_markStack, &_revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5519
                              &mrias_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5520
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5521
    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
  5522
    // 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
  5523
    // mod union table.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5524
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5525
      ModUnionClosure modUnionClosure(&_modUnionTable);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5526
      _ct->ct_bs()->dirty_card_iterate(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5527
                      _cmsGen->used_region(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5528
                      &modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5529
      _ct->ct_bs()->dirty_card_iterate(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5530
                      _permGen->used_region(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5531
                      &modUnionClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5532
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5533
    // Having transferred these marks into the modUnionTable, we just need
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5534
    // to rescan the marked objects on the dirty cards in the modUnionTable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5535
    // The initial marking may have been done during an asynchronous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5536
    // collection so there may be dirty bits in the mod-union table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5537
    const int alignment =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5538
      CardTableModRefBS::card_size * BitsPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5539
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5540
      // ... First handle dirty cards in CMS gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5541
      markFromDirtyCardsClosure.set_space(_cmsGen->cmsSpace());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5542
      MemRegion ur = _cmsGen->used_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5543
      HeapWord* lb = ur.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5544
      HeapWord* ub = (HeapWord*)round_to((intptr_t)ur.end(), alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5545
      MemRegion cms_span(lb, ub);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5546
      _modUnionTable.dirty_range_iterate_clear(cms_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5547
                                               &markFromDirtyCardsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5548
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5549
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5550
        gclog_or_tty->print(" (re-scanned "SIZE_FORMAT" dirty cards in cms gen) ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5551
          markFromDirtyCardsClosure.num_dirty_cards());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5552
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5553
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5554
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5555
      // .. and then repeat for dirty cards in perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5556
      markFromDirtyCardsClosure.set_space(_permGen->cmsSpace());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5557
      MemRegion ur = _permGen->used_region();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5558
      HeapWord* lb = ur.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5559
      HeapWord* ub = (HeapWord*)round_to((intptr_t)ur.end(), alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5560
      MemRegion perm_span(lb, ub);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5561
      _modUnionTable.dirty_range_iterate_clear(perm_span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5562
                                               &markFromDirtyCardsClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5563
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5564
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5565
        gclog_or_tty->print(" (re-scanned "SIZE_FORMAT" dirty cards in perm gen) ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5566
          markFromDirtyCardsClosure.num_dirty_cards());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5567
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5568
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5569
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5570
  if (VerifyDuringGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5571
      GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5572
    HandleMark hm;  // Discard invalid handles created during verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5573
    Universe::verify(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5574
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5575
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5576
    TraceTime t("root rescan", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5577
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5578
    verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5579
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5580
    gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5581
    GenCollectedHeap::StrongRootsScope srs(gch);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5582
    gch->gen_process_strong_roots(_cmsGen->level(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5583
                                  true,  // younger gens as roots
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5584
                                  false, // use the local StrongRootsScope
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5585
                                  true,  // collecting perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5586
                                  SharedHeap::ScanningOption(roots_scanning_options()),
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5587
                                  &mrias_cl,
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5588
                                  true,   // walk code active on stacks
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5589
                                  NULL);
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5590
    assert(should_unload_classes()
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5591
           || (roots_scanning_options() & SharedHeap::SO_CodeCache),
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2885
diff changeset
  5592
           "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5593
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5594
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5595
  // Restore evacuated mark words, if any, used for overflow list links
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5596
  if (!CMSOverflowEarlyRestoration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5597
    restore_preserved_marks_if_any();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5598
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5599
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5600
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5601
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5602
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5603
// Parallel Reference Processing Task Proxy Class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5604
////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5605
class CMSRefProcTaskProxy: public AbstractGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5606
  typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5607
  CMSCollector*          _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5608
  CMSBitMap*             _mark_bit_map;
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5609
  const MemRegion        _span;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5610
  OopTaskQueueSet*       _task_queues;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5611
  ParallelTaskTerminator _term;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5612
  ProcessTask&           _task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5613
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5614
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5615
  CMSRefProcTaskProxy(ProcessTask&     task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5616
                      CMSCollector*    collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5617
                      const MemRegion& span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5618
                      CMSBitMap*       mark_bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5619
                      int              total_workers,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5620
                      OopTaskQueueSet* task_queues):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5621
    AbstractGangTask("Process referents by policy in parallel"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5622
    _task(task),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5623
    _collector(collector), _span(span), _mark_bit_map(mark_bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5624
    _task_queues(task_queues),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5625
    _term(total_workers, task_queues)
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5626
    {
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5627
      assert(_collector->_span.equals(_span) && !_span.is_empty(),
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5628
             "Inconsistency in _span");
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5629
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5630
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5631
  OopTaskQueueSet* task_queues() { return _task_queues; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5632
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5633
  OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5634
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5635
  ParallelTaskTerminator* terminator() { return &_term; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5636
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5637
  void do_work_steal(int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5638
                     CMSParDrainMarkingStackClosure* drain,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5639
                     CMSParKeepAliveClosure* keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5640
                     int* seed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5641
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5642
  virtual void work(int i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5643
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5644
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5645
void CMSRefProcTaskProxy::work(int i) {
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5646
  assert(_collector->_span.equals(_span), "Inconsistency in _span");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5647
  CMSParKeepAliveClosure par_keep_alive(_collector, _span,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5648
                                        _mark_bit_map,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5649
                                        &_collector->_revisitStack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5650
                                        work_queue(i));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5651
  CMSParDrainMarkingStackClosure par_drain_stack(_collector, _span,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5652
                                                 _mark_bit_map,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5653
                                                 &_collector->_revisitStack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5654
                                                 work_queue(i));
390
2e094c1be4af 6662086: 6u4+, 7b11+: CMS never clears referents when -XX:+ParallelRefProcEnabled
ysr
parents: 360
diff changeset
  5655
  CMSIsAliveClosure is_alive_closure(_span, _mark_bit_map);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5656
  _task.work(i, is_alive_closure, par_keep_alive, par_drain_stack);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5657
  if (_task.marks_oops_alive()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5658
    do_work_steal(i, &par_drain_stack, &par_keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5659
                  _collector->hash_seed(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5660
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5661
  assert(work_queue(i)->size() == 0, "work_queue should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5662
  assert(_collector->_overflow_list == NULL, "non-empty _overflow_list");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5663
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5664
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5665
class CMSRefEnqueueTaskProxy: public AbstractGangTask {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5666
  typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5667
  EnqueueTask& _task;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5668
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5669
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5670
  CMSRefEnqueueTaskProxy(EnqueueTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5671
    : AbstractGangTask("Enqueue reference objects in parallel"),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5672
      _task(task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5673
  { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5674
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5675
  virtual void work(int i)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5676
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5677
    _task.work(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5678
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5679
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5680
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5681
CMSParKeepAliveClosure::CMSParKeepAliveClosure(CMSCollector* collector,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5682
  MemRegion span, CMSBitMap* bit_map, CMSMarkStack* revisit_stack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5683
  OopTaskQueue* work_queue):
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5684
   Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5685
   _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5686
   _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5687
   _work_queue(work_queue),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5688
   _mark_and_push(collector, span, bit_map, revisit_stack, work_queue),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5689
   _low_water_mark(MIN2((uint)(work_queue->max_elems()/4),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5690
                        (uint)(CMSWorkQueueDrainThreshold * ParallelGCThreads)))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5691
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5692
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5693
// . see if we can share work_queues with ParNew? XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5694
void CMSRefProcTaskProxy::do_work_steal(int i,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5695
  CMSParDrainMarkingStackClosure* drain,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5696
  CMSParKeepAliveClosure* keep_alive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5697
  int* seed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5698
  OopTaskQueue* work_q = work_queue(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5699
  NOT_PRODUCT(int num_steals = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5700
  oop obj_to_scan;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5701
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5702
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5703
    // Completely finish any left over work from (an) earlier round(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5704
    drain->trim_queue(0);
2346
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  5705
    size_t num_from_overflow_list = MIN2((size_t)(work_q->max_elems() - work_q->size())/4,
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  5706
                                         (size_t)ParGCDesiredObjsFromOverflowList);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5707
    // Now check if there's any work in the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5708
    if (_collector->par_take_from_overflow_list(num_from_overflow_list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5709
                                                work_q)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5710
      // Found something in global overflow list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5711
      // not yet ready to go stealing work from others.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5712
      // We'd like to assert(work_q->size() != 0, ...)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5713
      // because we just took work from the overflow list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5714
      // but of course we can't, since all of that might have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5715
      // been already stolen from us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5716
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5717
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5718
    // Verify that we have no work before we resort to stealing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5719
    assert(work_q->size() == 0, "Have work, shouldn't steal");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5720
    // Try to steal from other queues that have work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5721
    if (task_queues()->steal(i, seed, /* reference */ obj_to_scan)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5722
      NOT_PRODUCT(num_steals++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5723
      assert(obj_to_scan->is_oop(), "Oops, not an oop!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5724
      assert(_mark_bit_map->isMarked((HeapWord*)obj_to_scan), "Stole an unmarked oop?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5725
      // Do scanning work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5726
      obj_to_scan->oop_iterate(keep_alive);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5727
      // Loop around, finish this work, and try to steal some more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5728
    } else if (terminator()->offer_termination()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5729
      break;  // nirvana from the infinite cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5730
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5731
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5732
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5733
    if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5734
      gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5735
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5736
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5737
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5738
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5739
void CMSRefProcTaskExecutor::execute(ProcessTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5740
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5741
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5742
  WorkGang* workers = gch->workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5743
  assert(workers != NULL, "Need parallel worker threads.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5744
  int n_workers = workers->total_workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5745
  CMSRefProcTaskProxy rp_task(task, &_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5746
                              _collector.ref_processor()->span(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5747
                              _collector.markBitMap(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5748
                              n_workers, _collector.task_queues());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5749
  workers->run_task(&rp_task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5750
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5751
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5752
void CMSRefProcTaskExecutor::execute(EnqueueTask& task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5753
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5754
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5755
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5756
  WorkGang* workers = gch->workers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5757
  assert(workers != NULL, "Need parallel worker threads.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5758
  CMSRefEnqueueTaskProxy enq_task(task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5759
  workers->run_task(&enq_task);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5760
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5761
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5762
void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5763
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5764
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5765
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5766
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5767
  ReferenceProcessor* rp = ref_processor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5768
  assert(rp->span().equals(_span), "Spans should be equal");
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5769
  assert(!rp->enqueuing_is_done(), "Enqueuing should not be complete");
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5770
  // Process weak references.
1610
5dddd195cc86 6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents: 1606
diff changeset
  5771
  rp->setup_policy(clear_all_soft_refs);
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5772
  verify_work_stacks_empty();
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5773
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5774
  CMSKeepAliveClosure cmsKeepAliveClosure(this, _span, &_markBitMap,
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5775
                                          &_markStack, &_revisitStack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  5776
                                          false /* !preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5777
  CMSDrainMarkingStackClosure cmsDrainMarkingStackClosure(this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5778
                                _span, &_markBitMap, &_markStack,
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  5779
                                &cmsKeepAliveClosure, false /* !preclean */);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5780
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5781
    TraceTime t("weak refs processing", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5782
    if (rp->processing_is_mt()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5783
      CMSRefProcTaskExecutor task_executor(*this);
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5784
      rp->process_discovered_references(&_is_alive_closure,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5785
                                        &cmsKeepAliveClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5786
                                        &cmsDrainMarkingStackClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5787
                                        &task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5788
    } else {
1606
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  5789
      rp->process_discovered_references(&_is_alive_closure,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5790
                                        &cmsKeepAliveClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5791
                                        &cmsDrainMarkingStackClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5792
                                        NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5793
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5794
    verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5795
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5796
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  5797
  if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5798
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5799
      TraceTime t("class unloading", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5800
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5801
      // Follow SystemDictionary roots and unload classes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5802
      bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5803
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5804
      // Follow CodeCache roots and unload any methods marked for unloading
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5805
      CodeCache::do_unloading(&_is_alive_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5806
                              &cmsKeepAliveClosure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5807
                              purged_class);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5808
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5809
      cmsDrainMarkingStackClosure.do_void();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5810
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5811
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5812
      // Update subklass/sibling/implementor links in KlassKlass descendants
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5813
      assert(!_revisitStack.isEmpty(), "revisit stack should not be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5814
      oop k;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5815
      while ((k = _revisitStack.pop()) != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5816
        ((Klass*)(oopDesc*)k)->follow_weak_klass_links(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5817
                       &_is_alive_closure,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5818
                       &cmsKeepAliveClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5819
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5820
      assert(!ClassUnloading ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5821
             (_markStack.isEmpty() && overflow_list_is_empty()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5822
             "Should not have found new reachable objects");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5823
      assert(_revisitStack.isEmpty(), "revisit stack should have been drained");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5824
      cmsDrainMarkingStackClosure.do_void();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5825
      verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5826
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5827
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5828
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5829
      TraceTime t("scrub symbol & string tables", PrintGCDetails, false, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5830
      // Now clean up stale oops in SymbolTable and StringTable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5831
      SymbolTable::unlink(&_is_alive_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5832
      StringTable::unlink(&_is_alive_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5833
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5834
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5835
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5836
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5837
  // Restore any preserved marks as a result of mark stack or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5838
  // work queue overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5839
  restore_preserved_marks_if_any();  // done single-threaded for now
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5840
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5841
  rp->set_enqueuing_is_done(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5842
  if (rp->processing_is_mt()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5843
    CMSRefProcTaskExecutor task_executor(*this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5844
    rp->enqueue_discovered_references(&task_executor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5845
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5846
    rp->enqueue_discovered_references(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5847
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5848
  rp->verify_no_references_recorded();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5849
  assert(!rp->discovery_enabled(), "should have been disabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5850
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5851
  // JVMTI object tagging is based on JNI weak refs. If any of these
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5852
  // refs were cleared then JVMTI needs to update its maps and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5853
  // maybe post ObjectFrees to agents.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5854
  JvmtiExport::cms_ref_processing_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5855
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5856
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5857
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5858
void CMSCollector::check_correct_thread_executing() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5859
  Thread* t = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5860
  // Only the VM thread or the CMS thread should be here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5861
  assert(t->is_ConcurrentGC_thread() || t->is_VM_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5862
         "Unexpected thread type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5863
  // If this is the vm thread, the foreground process
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5864
  // should not be waiting.  Note that _foregroundGCIsActive is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5865
  // true while the foreground collector is waiting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5866
  if (_foregroundGCShouldWait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5867
    // We cannot be the VM thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5868
    assert(t->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5869
           "Should be CMS thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5870
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5871
    // We can be the CMS thread only if we are in a stop-world
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5872
    // phase of CMS collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5873
    if (t->is_ConcurrentGC_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5874
      assert(_collectorState == InitialMarking ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5875
             _collectorState == FinalMarking,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5876
             "Should be a stop-world phase");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5877
      // The CMS thread should be holding the CMS_token.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5878
      assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5879
             "Potential interference with concurrently "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5880
             "executing VM thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5881
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5882
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5883
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5884
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5885
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5886
void CMSCollector::sweep(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5887
  assert(_collectorState == Sweeping, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5888
  check_correct_thread_executing();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5889
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5890
  verify_overflow_empty();
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5891
  increment_sweep_count();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5892
  _inter_sweep_timer.stop();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5893
  _inter_sweep_estimate.sample(_inter_sweep_timer.seconds());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5894
  size_policy()->avg_cms_free_at_sweep()->sample(_cmsGen->free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5895
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5896
  // PermGen verification support: If perm gen sweeping is disabled in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5897
  // this cycle, we preserve the perm gen object "deadness" information
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5898
  // in the perm_gen_verify_bit_map. In order to do that we traverse
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5899
  // 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
  5900
  if (verifying() && !should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5901
    assert(perm_gen_verify_bit_map()->sizeInBits() != 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5902
           "Should have already been allocated");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5903
    MarkDeadObjectsClosure mdo(this, _permGen->cmsSpace(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5904
                               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
  5905
    if (asynch) {
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5906
      CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(),
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5907
                               bitMapLock());
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5908
      _permGen->cmsSpace()->blk_iterate(&mdo);
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5909
    } else {
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5910
      // 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
  5911
      // the requisite locks/tokens.
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5912
      _permGen->cmsSpace()->blk_iterate(&mdo);
09c6284b0f5e 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()"
ysr
parents: 1
diff changeset
  5913
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5914
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5915
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5916
  assert(!_intra_sweep_timer.is_active(), "Should not be active");
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5917
  _intra_sweep_timer.reset();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5918
  _intra_sweep_timer.start();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5919
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5920
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5921
    CMSPhaseAccounting pa(this, "sweep", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5922
    // First sweep the old gen then the perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5923
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5924
      CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5925
                               bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5926
      sweepWork(_cmsGen, asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5927
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5928
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5929
    // Now repeat for perm gen
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  5930
    if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5931
      CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5932
                             bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5933
      sweepWork(_permGen, asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5934
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5935
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5936
    // Update Universe::_heap_*_at_gc figures.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5937
    // We need all the free list locks to make the abstract state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5938
    // transition from Sweeping to Resetting. See detailed note
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5939
    // further below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5940
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5941
      CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5942
                               _permGen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5943
      // Update heap occupancy information which is used as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5944
      // input to soft ref clearing policy at the next gc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5945
      Universe::update_heap_info_at_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5946
      _collectorState = Resizing;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5947
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5948
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5949
    // already have needed locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5950
    sweepWork(_cmsGen,  asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5951
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  5952
    if (should_unload_classes()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5953
      sweepWork(_permGen, asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5954
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5955
    // Update heap occupancy information which is used as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5956
    // input to soft ref clearing policy at the next gc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5957
    Universe::update_heap_info_at_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5958
    _collectorState = Resizing;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5959
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5960
  verify_work_stacks_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5961
  verify_overflow_empty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5962
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5963
  _intra_sweep_timer.stop();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5964
  _intra_sweep_estimate.sample(_intra_sweep_timer.seconds());
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5965
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5966
  _inter_sweep_timer.reset();
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  5967
  _inter_sweep_timer.start();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5968
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5969
  update_time_of_last_gc(os::javaTimeMillis());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5970
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5971
  // NOTE on abstract state transitions:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5972
  // Mutators allocate-live and/or mark the mod-union table dirty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5973
  // based on the state of the collection.  The former is done in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5974
  // the interval [Marking, Sweeping] and the latter in the interval
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5975
  // [Marking, Sweeping).  Thus the transitions into the Marking state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5976
  // and out of the Sweeping state must be synchronously visible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5977
  // globally to the mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5978
  // The transition into the Marking state happens with the world
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5979
  // stopped so the mutators will globally see it.  Sweeping is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5980
  // done asynchronously by the background collector so the transition
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5981
  // from the Sweeping state to the Resizing state must be done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5982
  // under the freelistLock (as is the check for whether to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5983
  // allocate-live and whether to dirty the mod-union table).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5984
  assert(_collectorState == Resizing, "Change of collector state to"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5985
    " Resizing must be done under the freelistLocks (plural)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5986
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5987
  // Now that sweeping has been completed, if the GCH's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5988
  // incremental_collection_will_fail flag is set, clear it,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5989
  // thus inviting a younger gen collection to promote into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5990
  // this generation. If such a promotion may still fail,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5991
  // the flag will be set again when a young collection is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5992
  // attempted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5993
  // I think the incremental_collection_will_fail flag's use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5994
  // is specific to a 2 generation collection policy, so i'll
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5995
  // assert that that's the configuration we are operating within.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5996
  // The use of the flag can and should be generalized appropriately
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5997
  // in the future to deal with a general n-generation system.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5998
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5999
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6000
  assert(gch->collector_policy()->is_two_generation_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6001
         "Resetting of incremental_collection_will_fail flag"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6002
         " may be incorrect otherwise");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6003
  gch->clear_incremental_collection_will_fail();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6004
  gch->update_full_collections_completed(_collection_count_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6005
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6006
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6007
// FIX ME!!! Looks like this belongs in CFLSpace, with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6008
// CMSGen merely delegating to it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6009
void ConcurrentMarkSweepGeneration::setNearLargestChunk() {
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6010
  double nearLargestPercent = FLSLargestBlockCoalesceProximity;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6011
  HeapWord*  minAddr        = _cmsSpace->bottom();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6012
  HeapWord*  largestAddr    =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6013
    (HeapWord*) _cmsSpace->dictionary()->findLargestDict();
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6014
  if (largestAddr == NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6015
    // The dictionary appears to be empty.  In this case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6016
    // try to coalesce at the end of the heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6017
    largestAddr = _cmsSpace->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6018
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6019
  size_t largestOffset     = pointer_delta(largestAddr, minAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6020
  size_t nearLargestOffset =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6021
    (size_t)((double)largestOffset * nearLargestPercent) - MinChunkSize;
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6022
  if (PrintFLSStatistics != 0) {
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6023
    gclog_or_tty->print_cr(
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6024
      "CMS: Large Block: " PTR_FORMAT ";"
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6025
      " Proximity: " PTR_FORMAT " -> " PTR_FORMAT,
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6026
      largestAddr,
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6027
      _cmsSpace->nearLargestChunk(), minAddr + nearLargestOffset);
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6028
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6029
  _cmsSpace->set_nearLargestChunk(minAddr + nearLargestOffset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6030
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6031
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6032
bool ConcurrentMarkSweepGeneration::isNearLargestChunk(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6033
  return addr >= _cmsSpace->nearLargestChunk();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6034
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6035
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6036
FreeChunk* ConcurrentMarkSweepGeneration::find_chunk_at_end() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6037
  return _cmsSpace->find_chunk_at_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6038
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6040
void ConcurrentMarkSweepGeneration::update_gc_stats(int current_level,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6041
                                                    bool full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6042
  // The next lower level has been collected.  Gather any statistics
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6043
  // that are of interest at this point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6044
  if (!full && (current_level + 1) == level()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6045
    // Gather statistics on the young generation collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6046
    collector()->stats().record_gc0_end(used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6047
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6048
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6049
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6050
CMSAdaptiveSizePolicy* ConcurrentMarkSweepGeneration::size_policy() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6051
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6052
  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6053
    "Wrong type of heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6054
  CMSAdaptiveSizePolicy* sp = (CMSAdaptiveSizePolicy*)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6055
    gch->gen_policy()->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6056
  assert(sp->is_gc_cms_adaptive_size_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6057
    "Wrong type of size policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6058
  return sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6059
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6060
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6061
void ConcurrentMarkSweepGeneration::rotate_debug_collection_type() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6062
  if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6063
    gclog_or_tty->print("Rotate from %d ", _debug_collection_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6064
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6065
  _debug_collection_type = (CollectionTypes) (_debug_collection_type + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6066
  _debug_collection_type =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6067
    (CollectionTypes) (_debug_collection_type % Unknown_collection_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6068
  if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6069
    gclog_or_tty->print_cr("to %d ", _debug_collection_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6070
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6071
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6072
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6073
void CMSCollector::sweepWork(ConcurrentMarkSweepGeneration* gen,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6074
  bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6075
  // We iterate over the space(s) underlying this generation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6076
  // checking the mark bit map to see if the bits corresponding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6077
  // to specific blocks are marked or not. Blocks that are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6078
  // marked are live and are not swept up. All remaining blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6079
  // are swept up, with coalescing on-the-fly as we sweep up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6080
  // contiguous free and/or garbage blocks:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6081
  // We need to ensure that the sweeper synchronizes with allocators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6082
  // and stop-the-world collectors. In particular, the following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6083
  // locks are used:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6084
  // . CMS token: if this is held, a stop the world collection cannot occur
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6085
  // . freelistLock: if this is held no allocation can occur from this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6086
  //                 generation by another thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6087
  // . bitMapLock: if this is held, no other thread can access or update
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6088
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6089
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6090
  // Note that we need to hold the freelistLock if we use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6091
  // block iterate below; else the iterator might go awry if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6092
  // a mutator (or promotion) causes block contents to change
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6093
  // (for instance if the allocator divvies up a block).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6094
  // If we hold the free list lock, for all practical purposes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6095
  // young generation GC's can't occur (they'll usually need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6096
  // promote), so we might as well prevent all young generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6097
  // GC's while we do a sweeping step. For the same reason, we might
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6098
  // as well take the bit map lock for the entire duration
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6099
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6100
  // check that we hold the requisite locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6101
  assert(have_cms_token(), "Should hold cms token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6102
  assert(   (asynch && ConcurrentMarkSweepThread::cms_thread_has_cms_token())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6103
         || (!asynch && ConcurrentMarkSweepThread::vm_thread_has_cms_token()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6104
        "Should possess CMS token to sweep");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6105
  assert_lock_strong(gen->freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6106
  assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6107
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6108
  assert(!_inter_sweep_timer.is_active(), "Was switched off in an outer context");
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6109
  assert(_intra_sweep_timer.is_active(),  "Was switched on  in an outer context");
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6110
  gen->cmsSpace()->beginSweepFLCensus((float)(_inter_sweep_timer.seconds()),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6111
                                      _inter_sweep_estimate.padded_average(),
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6112
                                      _intra_sweep_estimate.padded_average());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6113
  gen->setNearLargestChunk();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6114
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6115
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6116
    SweepClosure sweepClosure(this, gen, &_markBitMap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6117
                            CMSYield && asynch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6118
    gen->cmsSpace()->blk_iterate_careful(&sweepClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6119
    // We need to free-up/coalesce garbage/blocks from a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6120
    // co-terminal free run. This is done in the SweepClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6121
    // destructor; so, do not remove this scope, else the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6122
    // end-of-sweep-census below will be off by a little bit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6123
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6124
  gen->cmsSpace()->sweep_completed();
4574
b2d5b0975515 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 4455
diff changeset
  6125
  gen->cmsSpace()->endSweepFLCensus(sweep_count());
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6126
  if (should_unload_classes()) {                // unloaded classes this cycle,
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6127
    _concurrent_cycles_since_last_unload = 0;   // ... reset count
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6128
  } else {                                      // did not unload classes,
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6129
    _concurrent_cycles_since_last_unload++;     // ... increment count
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  6130
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6131
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6132
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6133
// Reset CMS data structures (for now just the marking bit map)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6134
// preparatory for the next cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6135
void CMSCollector::reset(bool asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6136
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6137
  CMSAdaptiveSizePolicy* sp = size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6138
  AdaptiveSizePolicyOutput(sp, gch->total_collections());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6139
  if (asynch) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6140
    CMSTokenSyncWithLocks ts(true, bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6141
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6142
    // If the state is not "Resetting", the foreground  thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6143
    // has done a collection and the resetting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6144
    if (_collectorState != Resetting) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6145
      assert(_collectorState == Idling, "The state should only change"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6146
        " because the foreground collector has finished the collection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6147
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6148
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6149
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6150
    // Clear the mark bitmap (no grey objects to start with)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6151
    // for the next cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6152
    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6153
    CMSPhaseAccounting cmspa(this, "reset", !PrintGCDetails);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6154
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6155
    HeapWord* curAddr = _markBitMap.startWord();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6156
    while (curAddr < _markBitMap.endWord()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6157
      size_t remaining  = pointer_delta(_markBitMap.endWord(), curAddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6158
      MemRegion chunk(curAddr, MIN2(CMSBitMapYieldQuantum, remaining));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6159
      _markBitMap.clear_large_range(chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6160
      if (ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6161
          !foregroundGCIsActive() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6162
          CMSYield) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6163
        assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6164
               "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6165
        assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6166
        bitMapLock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6167
        ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6168
        ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6169
        stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6170
        if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6171
          incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6172
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6173
        icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6174
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6175
        // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6176
        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
  6177
                         ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6178
                         !CMSCollector::foregroundGCIsActive(); ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6179
          os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6180
          ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6181
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6182
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6183
        ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6184
        bitMapLock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6185
        startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6186
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6187
      curAddr = chunk.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6188
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6189
    _collectorState = Idling;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6190
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6191
    // already have the lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6192
    assert(_collectorState == Resetting, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6193
    assert_lock_strong(bitMapLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6194
    _markBitMap.clear_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6195
    _collectorState = Idling;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6196
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6197
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6198
  // Stop incremental mode after a cycle completes, so that any future cycles
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6199
  // are triggered by allocation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6200
  stop_icms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6201
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6202
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6203
    if (RotateCMSCollectionTypes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6204
      _cmsGen->rotate_debug_collection_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6205
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6206
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6207
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6208
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6209
void CMSCollector::do_CMS_operation(CMS_op_type op) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6210
  gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6211
  TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6212
  TraceTime t("GC", PrintGC, !PrintGCDetails, gclog_or_tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6213
  TraceCollectorStats tcs(counters());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6214
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6215
  switch (op) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6216
    case CMS_op_checkpointRootsInitial: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6217
      checkpointRootsInitial(true);       // asynch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6218
      if (PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6219
        _cmsGen->printOccupancy("initial-mark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6220
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6221
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6222
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6223
    case CMS_op_checkpointRootsFinal: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6224
      checkpointRootsFinal(true,    // asynch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6225
                           false,   // !clear_all_soft_refs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6226
                           false);  // !init_mark_was_synchronous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6227
      if (PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6228
        _cmsGen->printOccupancy("remark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6229
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6230
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6231
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6232
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6233
      fatal("No such CMS_op");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6234
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6235
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6236
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6237
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6238
size_t const CMSCollector::skip_header_HeapWords() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6239
  return FreeChunk::header_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6240
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6241
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6242
// Try and collect here conditions that should hold when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6243
// CMS thread is exiting. The idea is that the foreground GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6244
// thread should not be blocked if it wants to terminate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6245
// the CMS thread and yet continue to run the VM for a while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6246
// after that.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6247
void CMSCollector::verify_ok_to_terminate() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6248
  assert(Thread::current()->is_ConcurrentGC_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6249
         "should be called by CMS thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6250
  assert(!_foregroundGCShouldWait, "should be false");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6251
  // We could check here that all the various low-level locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6252
  // are not held by the CMS thread, but that is overkill; see
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6253
  // also CMSThread::verify_ok_to_terminate() where the CGC_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6254
  // is checked.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6255
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6256
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6257
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6258
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
  6259
   assert(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1),
dcf9714addbe 6684579: SoftReference processing can be made more efficient
ysr
parents: 1605
diff changeset
  6260
          "missing Printezis mark?");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6261
  HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6262
  size_t size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6263
  assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6264
         "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6265
  assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6266
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6267
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6268
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6269
// A variant of the above (block_size_using_printezis_bits()) except
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6270
// that we return 0 if the P-bits are not yet set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6271
size_t CMSCollector::block_size_if_printezis_bits(HeapWord* addr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6272
  if (_markBitMap.isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6273
    assert(_markBitMap.isMarked(addr + 1), "Missing Printezis bit?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6274
    HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6275
    size_t size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6276
    assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6277
           "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6278
    assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6279
    return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6280
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6281
    assert(!_markBitMap.isMarked(addr + 1), "Bit map inconsistency?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6282
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6283
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6284
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6285
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6286
HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6287
  size_t sz = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6288
  oop p = (oop)addr;
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6289
  if (p->klass_or_null() != NULL && p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6290
    sz = CompactibleFreeListSpace::adjustObjectSize(p->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6291
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6292
    sz = block_size_using_printezis_bits(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6293
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6294
  assert(sz > 0, "size must be nonzero");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6295
  HeapWord* next_block = addr + sz;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6296
  HeapWord* next_card  = (HeapWord*)round_to((uintptr_t)next_block,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6297
                                             CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6298
  assert(round_down((uintptr_t)addr,      CardTableModRefBS::card_size) <
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6299
         round_down((uintptr_t)next_card, CardTableModRefBS::card_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6300
         "must be different cards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6301
  return next_card;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6302
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6303
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6304
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6305
// CMS Bit Map Wrapper /////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6306
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6307
// Construct a CMS bit map infrastructure, but don't create the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6308
// bit vector itself. That is done by a separate call CMSBitMap::allocate()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6309
// further below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6310
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
  6311
  _bm(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6312
  _shifter(shifter),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6313
  _lock(mutex_rank >= 0 ? new Mutex(mutex_rank, mutex_name, true) : NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6314
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6315
  _bmStartWord = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6316
  _bmWordSize  = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6317
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6318
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6319
bool CMSBitMap::allocate(MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6320
  _bmStartWord = mr.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6321
  _bmWordSize  = mr.word_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6322
  ReservedSpace brs(ReservedSpace::allocation_align_size_up(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6323
                     (_bmWordSize >> (_shifter + LogBitsPerByte)) + 1));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6324
  if (!brs.is_reserved()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6325
    warning("CMS bit map allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6326
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6327
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6328
  // For now we'll just commit all of the bit map up fromt.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6329
  // Later on we'll try to be more parsimonious with swap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6330
  if (!_virtual_space.initialize(brs, brs.size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6331
    warning("CMS bit map backing store failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6332
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6333
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6334
  assert(_virtual_space.committed_size() == brs.size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6335
         "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
  6336
  _bm.set_map((BitMap::bm_word_t*)_virtual_space.low());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6337
  assert(_virtual_space.committed_size() << (_shifter + LogBitsPerByte) >=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6338
         _bmWordSize, "inconsistency in bit map sizing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6339
  _bm.set_size(_bmWordSize >> _shifter);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6340
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6341
  // bm.clear(); // can we rely on getting zero'd memory? verify below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6342
  assert(isAllClear(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6343
         "Expected zero'd memory from ReservedSpace constructor");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6344
  assert(_bm.size() == heapWordDiffToOffsetDiff(sizeInWords()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6345
         "consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6346
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6347
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6348
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6349
void CMSBitMap::dirty_range_iterate_clear(MemRegion mr, MemRegionClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6350
  HeapWord *next_addr, *end_addr, *last_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6351
  assert_locked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6352
  assert(covers(mr), "out-of-range error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6353
  // XXX assert that start and end are appropriately aligned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6354
  for (next_addr = mr.start(), end_addr = mr.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6355
       next_addr < end_addr; next_addr = last_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6356
    MemRegion dirty_region = getAndClearMarkedRegion(next_addr, end_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6357
    last_addr = dirty_region.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6358
    if (!dirty_region.is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6359
      cl->do_MemRegion(dirty_region);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6360
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6361
      assert(last_addr == end_addr, "program logic");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6362
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6363
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6364
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6365
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6366
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6367
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6368
void CMSBitMap::assert_locked() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6369
  CMSLockVerifier::assert_locked(lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6370
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6371
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6372
bool CMSBitMap::covers(MemRegion mr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6373
  // assert(_bm.map() == _virtual_space.low(), "map inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6374
  assert((size_t)_bm.size() == (_bmWordSize >> _shifter),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6375
         "size inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6376
  return (mr.start() >= _bmStartWord) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6377
         (mr.end()   <= endWord());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6378
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6379
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6380
bool CMSBitMap::covers(HeapWord* start, size_t size) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6381
    return (start >= _bmStartWord && (start + size) <= endWord());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6382
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6383
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6384
void CMSBitMap::verifyNoOneBitsInRange(HeapWord* left, HeapWord* right) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6385
  // verify that there are no 1 bits in the interval [left, right)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6386
  FalseBitMapClosure falseBitMapClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6387
  iterate(&falseBitMapClosure, left, right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6388
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6389
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6390
void CMSBitMap::region_invariant(MemRegion mr)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6391
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6392
  assert_locked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6393
  // mr = mr.intersection(MemRegion(_bmStartWord, _bmWordSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6394
  assert(!mr.is_empty(), "unexpected empty region");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6395
  assert(covers(mr), "mr should be covered by bit map");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6396
  // convert address range into offset range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6397
  size_t start_ofs = heapWordToOffset(mr.start());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6398
  // Make sure that end() is appropriately aligned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6399
  assert(mr.end() == (HeapWord*)round_to((intptr_t)mr.end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6400
                        (1 << (_shifter+LogHeapWordSize))),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6401
         "Misaligned mr.end()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6402
  size_t end_ofs   = heapWordToOffset(mr.end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6403
  assert(end_ofs > start_ofs, "Should mark at least one bit");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6404
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6405
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6406
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6407
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6408
bool CMSMarkStack::allocate(size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6409
  // allocate a stack of the requisite depth
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6410
  ReservedSpace rs(ReservedSpace::allocation_align_size_up(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6411
                   size * sizeof(oop)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6412
  if (!rs.is_reserved()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6413
    warning("CMSMarkStack allocation failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6414
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6415
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6416
  if (!_virtual_space.initialize(rs, rs.size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6417
    warning("CMSMarkStack backing store failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6418
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6419
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6420
  assert(_virtual_space.committed_size() == rs.size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6421
         "didn't reserve backing store for all of CMS stack?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6422
  _base = (oop*)(_virtual_space.low());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6423
  _index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6424
  _capacity = size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6425
  NOT_PRODUCT(_max_depth = 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6426
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6427
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6428
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6429
// XXX FIX ME !!! In the MT case we come in here holding a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6430
// leaf lock. For printing we need to take a further lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6431
// which has lower rank. We need to recallibrate the two
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6432
// lock-ranks involved in order to be able to rpint the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6433
// messages below. (Or defer the printing to the caller.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6434
// For now we take the expedient path of just disabling the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6435
// messages for the problematic case.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6436
void CMSMarkStack::expand() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6437
  assert(_capacity <= CMSMarkStackSizeMax, "stack bigger than permitted");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6438
  if (_capacity == CMSMarkStackSizeMax) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6439
    if (_hit_limit++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6440
      // We print a warning message only once per CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6441
      gclog_or_tty->print_cr(" (benign) Hit CMSMarkStack max size limit");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6442
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6443
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6444
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6445
  // Double capacity if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6446
  size_t new_capacity = MIN2(_capacity*2, CMSMarkStackSizeMax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6447
  // Do not give up existing stack until we have managed to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6448
  // get the double capacity that we desired.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6449
  ReservedSpace rs(ReservedSpace::allocation_align_size_up(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6450
                   new_capacity * sizeof(oop)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6451
  if (rs.is_reserved()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6452
    // Release the backing store associated with old stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6453
    _virtual_space.release();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6454
    // Reinitialize virtual space for new stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6455
    if (!_virtual_space.initialize(rs, rs.size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6456
      fatal("Not enough swap for expanded marking stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6457
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6458
    _base = (oop*)(_virtual_space.low());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6459
    _index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6460
    _capacity = new_capacity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6461
  } else if (_failed_double++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6462
    // Failed to double capacity, continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6463
    // we print a detail message only once per CMS cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6464
    gclog_or_tty->print(" (benign) Failed to expand marking stack from "SIZE_FORMAT"K to "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6465
            SIZE_FORMAT"K",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6466
            _capacity / K, new_capacity / K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6467
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6468
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6469
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6470
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6471
// Closures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6472
// XXX: there seems to be a lot of code  duplication here;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6473
// should refactor and consolidate common code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6474
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6475
// This closure is used to mark refs into the CMS generation in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6476
// the CMS bit map. Called at the first checkpoint. This closure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6477
// assumes that we do not need to re-mark dirty cards; if the CMS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6478
// generation on which this is used is not an oldest (modulo perm gen)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6479
// generation then this will lose younger_gen cards!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6480
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6481
MarkRefsIntoClosure::MarkRefsIntoClosure(
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6482
  MemRegion span, CMSBitMap* bitMap):
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6483
    _span(span),
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6484
    _bitMap(bitMap)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6485
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6486
    assert(_ref_processor == NULL, "deliberately left NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6487
    assert(_bitMap->covers(_span), "_bitMap/_span mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6488
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6489
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6490
void MarkRefsIntoClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6491
  // 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
  6492
  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
  6493
  HeapWord* addr = (HeapWord*)obj;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6494
  if (_span.contains(addr)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6495
    // 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
  6496
    _bitMap->mark(addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6497
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6498
}
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6499
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6500
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
  6501
void MarkRefsIntoClosure::do_oop(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6502
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6503
// A variant of the above, used for CMS marking verification.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6504
MarkRefsIntoVerifyClosure::MarkRefsIntoVerifyClosure(
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6505
  MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm):
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6506
    _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6507
    _verification_bm(verification_bm),
3913
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6508
    _cms_bm(cms_bm)
e049e6b81e11 6885169: merge of 4957990 and 6863023 causes conflict on do_nmethods
jrose
parents: 3912
diff changeset
  6509
{
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6510
    assert(_ref_processor == NULL, "deliberately left NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6511
    assert(_verification_bm->covers(_span), "_verification_bm/_span mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6512
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6513
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6514
void MarkRefsIntoVerifyClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6515
  // 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
  6516
  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
  6517
  HeapWord* addr = (HeapWord*)obj;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6518
  if (_span.contains(addr)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6519
    _verification_bm->mark(addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6520
    if (!_cms_bm->isMarked(addr)) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6521
      oop(addr)->print();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6522
      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
  6523
      fatal("... aborting");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6524
    }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6525
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6526
}
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6527
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6528
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
  6529
void MarkRefsIntoVerifyClosure::do_oop(narrowOop* p) { MarkRefsIntoVerifyClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6530
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6531
//////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6532
// MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6533
//////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6534
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6535
MarkRefsIntoAndScanClosure::MarkRefsIntoAndScanClosure(MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6536
                                                       ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6537
                                                       CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6538
                                                       CMSBitMap* mod_union_table,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6539
                                                       CMSMarkStack*  mark_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6540
                                                       CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6541
                                                       CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6542
                                                       bool should_yield,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6543
                                                       bool concurrent_precleaning):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6544
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6545
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6546
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6547
  _mark_stack(mark_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6548
  _pushAndMarkClosure(collector, span, rp, bit_map, mod_union_table,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6549
                      mark_stack, revisit_stack, concurrent_precleaning),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6550
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6551
  _concurrent_precleaning(concurrent_precleaning),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6552
  _freelistLock(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6553
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6554
  _ref_processor = rp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6555
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6556
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6557
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6558
// This closure is used to mark refs into the CMS generation at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6559
// second (final) checkpoint, and to scan and transitively follow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6560
// the unmarked oops. It is also used during the concurrent precleaning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6561
// phase while scanning objects on dirty cards in the CMS generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6562
// The marks are made in the marking bit map and the marking stack is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6563
// used for keeping the (newly) grey objects during the scan.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6564
// 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
  6565
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
  6566
  if (obj != NULL) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6567
    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
  6568
    HeapWord* addr = (HeapWord*)obj;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6569
    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
  6570
    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
  6571
           "overflow list should be empty");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6572
    if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6573
        !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6574
      // mark bit map (object is now grey)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6575
      _bit_map->mark(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6576
      // push on marking stack (stack should be empty), and drain the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6577
      // stack by applying this closure to the oops in the oops popped
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6578
      // 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
  6579
      bool res = _mark_stack->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6580
      assert(res, "Should have space to push on empty stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6581
      do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6582
        oop new_oop = _mark_stack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6583
        assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6584
        assert(new_oop->is_parsable(), "Found unparsable oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6585
        assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6586
               "only grey objects on this stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6587
        // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6588
        // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6589
        new_oop->oop_iterate(&_pushAndMarkClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6590
        // check if it's time to yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6591
        do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6592
      } while (!_mark_stack->isEmpty() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6593
               (!_concurrent_precleaning && take_from_overflow_list()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6594
        // if marking stack is empty, and we are not doing this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6595
        // during precleaning, then check the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6596
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6597
    assert(_mark_stack->isEmpty(), "post-condition (eager drainage)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6598
    assert(_collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6599
           "overflow list was drained above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6600
    // We could restore evacuated mark words, if any, used for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6601
    // overflow list links here because the overflow list is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6602
    // provably empty here. That would reduce the maximum
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6603
    // size requirements for preserved_{oop,mark}_stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6604
    // But we'll just postpone it until we are all done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6605
    // so we can just stream through.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6606
    if (!_concurrent_precleaning && CMSOverflowEarlyRestoration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6607
      _collector->restore_preserved_marks_if_any();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6608
      assert(_collector->no_preserved_marks(), "No preserved marks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6609
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6610
    assert(!CMSOverflowEarlyRestoration || _collector->no_preserved_marks(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6611
           "All preserved marks should have been restored above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6612
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6613
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6614
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6615
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
  6616
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
  6617
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6618
void MarkRefsIntoAndScanClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6619
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6620
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6621
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6622
  assert_lock_strong(_bit_map->lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6623
  // relinquish the free_list_lock and bitMaplock()
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  6624
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6625
  _bit_map->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6626
  _freelistLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6627
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6628
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6629
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6630
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6631
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6632
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6633
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6634
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6635
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6636
  // 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
  6637
  for (unsigned i = 0;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6638
       i < CMSYieldSleepCount &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6639
       ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6640
       !CMSCollector::foregroundGCIsActive();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6641
       ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6642
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6643
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6644
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6645
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6646
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6647
  _freelistLock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6648
  _bit_map->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6649
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6650
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6651
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6652
///////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6653
// Par_MarkRefsIntoAndScanClosure: a parallel version of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6654
//                                 MarkRefsIntoAndScanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6655
///////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6656
Par_MarkRefsIntoAndScanClosure::Par_MarkRefsIntoAndScanClosure(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6657
  CMSCollector* collector, MemRegion span, ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6658
  CMSBitMap* bit_map, OopTaskQueue* work_queue, CMSMarkStack*  revisit_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6659
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6660
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6661
  _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6662
  _low_water_mark(MIN2((uint)(work_queue->max_elems()/4),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6663
                       (uint)(CMSWorkQueueDrainThreshold * ParallelGCThreads))),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6664
  _par_pushAndMarkClosure(collector, span, rp, bit_map, work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6665
                          revisit_stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6666
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6667
  _ref_processor = rp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6668
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6669
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6670
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6671
// This closure is used to mark refs into the CMS generation at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6672
// second (final) checkpoint, and to scan and transitively follow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6673
// the unmarked oops. The marks are made in the marking bit map and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6674
// the work_queue is used for keeping the (newly) grey objects during
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6675
// the scan phase whence they are also available for stealing by parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6676
// threads. Since the marking bit map is shared, updates are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6677
// synchronized (via CAS).
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6678
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
  6679
  if (obj != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6680
    // Ignore mark word because this could be an already marked oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6681
    // 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
  6682
    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
  6683
    HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6684
    if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6685
        !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6686
      // mark bit map (object will become grey):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6687
      // It is possible for several threads to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6688
      // trying to "claim" this object concurrently;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6689
      // the unique thread that succeeds in marking the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6690
      // object first will do the subsequent push on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6691
      // to the work queue (or overflow list).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6692
      if (_bit_map->par_mark(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6693
        // push on work_queue (which may not be empty), and trim the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6694
        // queue to an appropriate length by applying this closure to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6695
        // the oops in the oops popped from the stack (i.e. blacken the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6696
        // grey objects)
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6697
        bool res = _work_queue->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6698
        assert(res, "Low water mark should be less than capacity?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6699
        trim_queue(_low_water_mark);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6700
      } // Else, another thread claimed the object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6701
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6702
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6703
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6704
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6705
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
  6706
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
  6707
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6708
// This closure is used to rescan the marked objects on the dirty cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6709
// in the mod union table and the card table proper.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6710
size_t ScanMarkedObjectsAgainCarefullyClosure::do_object_careful_m(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6711
  oop p, MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6712
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6713
  size_t size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6714
  HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6715
  DEBUG_ONLY(_collector->verify_work_stacks_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6716
  assert(_span.contains(addr), "we are scanning the CMS generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6717
  // check if it's time to yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6718
  if (do_yield_check()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6719
    // We yielded for some foreground stop-world work,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6720
    // and we have been asked to abort this ongoing preclean cycle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6721
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6722
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6723
  if (_bitMap->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6724
    // it's marked; is it potentially uninitialized?
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6725
    if (p->klass_or_null() != NULL) {
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  6726
      // If is_conc_safe is false, the object may be undergoing
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  6727
      // change by the VM outside a safepoint.  Don't try to
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  6728
      // scan it, but rather leave it for the remark phase.
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  6729
      if (CMSPermGenPrecleaningEnabled &&
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  6730
          (!p->is_conc_safe() || !p->is_parsable())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6731
        // Signal precleaning to redirty the card since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6732
        // the klass pointer is already installed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6733
        assert(size == 0, "Initial value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6734
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6735
        assert(p->is_parsable(), "must be parsable.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6736
        // an initialized object; ignore mark word in verification below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6737
        // since we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6738
        assert(p->is_oop(true), "should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6739
        if (p->is_objArray()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6740
          // objArrays are precisely marked; restrict scanning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6741
          // to dirty cards only.
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6742
          size = CompactibleFreeListSpace::adjustObjectSize(
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6743
                   p->oop_iterate(_scanningClosure, mr));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6744
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6745
          // A non-array may have been imprecisely marked; we need
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6746
          // to scan object in its entirety.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6747
          size = CompactibleFreeListSpace::adjustObjectSize(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6748
                   p->oop_iterate(_scanningClosure));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6749
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6750
        #ifdef DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6751
          size_t direct_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6752
            CompactibleFreeListSpace::adjustObjectSize(p->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6753
          assert(size == direct_size, "Inconsistency in size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6754
          assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6755
          if (!_bitMap->isMarked(addr+1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6756
            _bitMap->verifyNoOneBitsInRange(addr+2, addr+size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6757
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6758
            _bitMap->verifyNoOneBitsInRange(addr+2, addr+size-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6759
            assert(_bitMap->isMarked(addr+size-1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6760
                   "inconsistent Printezis mark");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6761
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6762
        #endif // DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6763
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6764
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6765
      // an unitialized object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6766
      assert(_bitMap->isMarked(addr+1), "missing Printezis mark?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6767
      HeapWord* nextOneAddr = _bitMap->getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6768
      size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6769
      assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6770
             "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6771
      // Note that pre-cleaning needn't redirty the card. OopDesc::set_klass()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6772
      // will dirty the card when the klass pointer is installed in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6773
      // object (signalling the completion of initialization).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6774
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6775
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6776
    // Either a not yet marked object or an uninitialized object
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6777
    if (p->klass_or_null() == NULL || !p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6778
      // An uninitialized object, skip to the next card, since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6779
      // we may not be able to read its P-bits yet.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6780
      assert(size == 0, "Initial value");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6781
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6782
      // An object not (yet) reached by marking: we merely need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6783
      // compute its size so as to go look at the next block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6784
      assert(p->is_oop(true), "should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6785
      size = CompactibleFreeListSpace::adjustObjectSize(p->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6786
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6787
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6788
  DEBUG_ONLY(_collector->verify_work_stacks_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6789
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6790
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6791
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6792
void ScanMarkedObjectsAgainCarefullyClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6793
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6794
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6795
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6796
  assert_lock_strong(_bitMap->lock());
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  6797
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6798
  // relinquish the free_list_lock and bitMaplock()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6799
  _bitMap->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6800
  _freelistLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6801
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6802
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6803
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6804
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6805
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6806
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6807
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6808
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6809
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6810
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6811
  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
  6812
                   ConcurrentMarkSweepThread::should_yield() &&
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  6813
                   !CMSCollector::foregroundGCIsActive(); ++i) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6814
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6815
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6816
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6817
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6818
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6819
  _freelistLock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6820
  _bitMap->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6821
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6822
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6823
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6824
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6825
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6826
// SurvivorSpacePrecleanClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6827
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6828
// This (single-threaded) closure is used to preclean the oops in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6829
// the survivor spaces.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6830
size_t SurvivorSpacePrecleanClosure::do_object_careful(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6831
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6832
  HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6833
  DEBUG_ONLY(_collector->verify_work_stacks_empty();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6834
  assert(!_span.contains(addr), "we are scanning the survivor spaces");
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6835
  assert(p->klass_or_null() != NULL, "object should be initializd");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6836
  assert(p->is_parsable(), "must be parsable.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6837
  // an initialized object; ignore mark word in verification below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6838
  // since we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6839
  assert(p->is_oop(true), "should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6840
  // Note that we do not yield while we iterate over
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6841
  // the interior oops of p, pushing the relevant ones
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6842
  // on our marking stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6843
  size_t size = p->oop_iterate(_scanning_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6844
  do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6845
  // Observe that below, we do not abandon the preclean
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6846
  // phase as soon as we should; rather we empty the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6847
  // marking stack before returning. This is to satisfy
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6848
  // some existing assertions. In general, it may be a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6849
  // good idea to abort immediately and complete the marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6850
  // from the grey objects at a later time.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6851
  while (!_mark_stack->isEmpty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6852
    oop new_oop = _mark_stack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6853
    assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6854
    assert(new_oop->is_parsable(), "Found unparsable oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6855
    assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6856
           "only grey objects on this stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6857
    // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6858
    // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6859
    new_oop->oop_iterate(_scanning_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6860
    // check if it's time to yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6861
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6862
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6863
  unsigned int after_count =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6864
    GenCollectedHeap::heap()->total_collections();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6865
  bool abort = (_before_count != after_count) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6866
               _collector->should_abort_preclean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6867
  return abort ? 0 : size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6868
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6869
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6870
void SurvivorSpacePrecleanClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6871
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6872
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6873
  assert_lock_strong(_bit_map->lock());
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  6874
  DEBUG_ONLY(RememberKlassesChecker smx(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6875
  // Relinquish the bit map lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6876
  _bit_map->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6877
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6878
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6879
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6880
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6881
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6882
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6883
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6884
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6885
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6886
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6887
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6888
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6889
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6890
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6891
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6892
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6893
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6894
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6895
  _bit_map->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6896
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6897
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6898
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6899
// This closure is used to rescan the marked objects on the dirty cards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6900
// in the mod union table and the card table proper. In the parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6901
// case, although the bitMap is shared, we do a single read so the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6902
// isMarked() query is "safe".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6903
bool ScanMarkedObjectsAgainClosure::do_object_bm(oop p, MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6904
  // Ignore mark word because we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6905
  assert(p->is_oop_or_null(true), "expected an oop or null");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6906
  HeapWord* addr = (HeapWord*)p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6907
  assert(_span.contains(addr), "we are scanning the CMS generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6908
  bool is_obj_array = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6909
  #ifdef DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6910
    if (!_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6911
      assert(_mark_stack->isEmpty(), "pre-condition (eager drainage)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6912
      assert(_collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6913
             "overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6914
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6915
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6916
  #endif // DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6917
  if (_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6918
    // Obj arrays are precisely marked, non-arrays are not;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6919
    // so we scan objArrays precisely and non-arrays in their
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6920
    // entirety.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6921
    if (p->is_objArray()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6922
      is_obj_array = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6923
      if (_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6924
        p->oop_iterate(_par_scan_closure, mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6925
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6926
        p->oop_iterate(_scan_closure, mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6927
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6928
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6929
      if (_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6930
        p->oop_iterate(_par_scan_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6931
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6932
        p->oop_iterate(_scan_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6933
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6934
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6935
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6936
  #ifdef DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6937
    if (!_parallel) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6938
      assert(_mark_stack->isEmpty(), "post-condition (eager drainage)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6939
      assert(_collector->overflow_list_is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6940
             "overflow list should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6941
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6942
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6943
  #endif // DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6944
  return is_obj_array;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6945
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6946
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6947
MarkFromRootsClosure::MarkFromRootsClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6948
                        MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6949
                        CMSBitMap* bitMap, CMSMarkStack*  markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6950
                        CMSMarkStack*  revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6951
                        bool should_yield, bool verifying):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6952
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6953
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6954
  _bitMap(bitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6955
  _mut(&collector->_modUnionTable),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6956
  _markStack(markStack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6957
  _revisitStack(revisitStack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6958
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6959
  _skipBits(0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6960
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6961
  assert(_markStack->isEmpty(), "stack should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6962
  _finger = _bitMap->startWord();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6963
  _threshold = _finger;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6964
  assert(_collector->_restart_addr == NULL, "Sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6965
  assert(_span.contains(_finger), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6966
  DEBUG_ONLY(_verifying = verifying;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6967
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6968
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6969
void MarkFromRootsClosure::reset(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6970
  assert(_markStack->isEmpty(), "would cause duplicates on stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6971
  assert(_span.contains(addr), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6972
  _finger = addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6973
  _threshold = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6974
                 (intptr_t)_finger, CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6975
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6976
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6977
// Should revisit to see if this should be restructured for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6978
// greater efficiency.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  6979
bool MarkFromRootsClosure::do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6980
  if (_skipBits > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6981
    _skipBits--;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  6982
    return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6983
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6984
  // convert offset into a HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6985
  HeapWord* addr = _bitMap->startWord() + offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6986
  assert(_bitMap->endWord() && addr < _bitMap->endWord(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6987
         "address out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6988
  assert(_bitMap->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6989
  if (_bitMap->isMarked(addr+1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6990
    // this is an allocated but not yet initialized object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6991
    assert(_skipBits == 0, "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6992
    _skipBits = 2;  // skip next two marked bits ("Printezis-marks")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6993
    oop p = oop(addr);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  6994
    if (p->klass_or_null() == NULL || !p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6995
      DEBUG_ONLY(if (!_verifying) {)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6996
        // We re-dirty the cards on which this object lies and increase
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6997
        // the _threshold so that we'll come back to scan this object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6998
        // during the preclean or remark phase. (CMSCleanOnEnter)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6999
        if (CMSCleanOnEnter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7000
          size_t sz = _collector->block_size_using_printezis_bits(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7001
          HeapWord* end_card_addr   = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7002
                                         (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
  7003
          MemRegion redirty_range = MemRegion(addr, end_card_addr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7004
          assert(!redirty_range.is_empty(), "Arithmetical tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7005
          // Bump _threshold to end_card_addr; note that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7006
          // _threshold cannot possibly exceed end_card_addr, anyhow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7007
          // This prevents future clearing of the card as the scan proceeds
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7008
          // to the right.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7009
          assert(_threshold <= end_card_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7010
                 "Because we are just scanning into this object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7011
          if (_threshold < end_card_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7012
            _threshold = end_card_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7013
          }
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  7014
          if (p->klass_or_null() != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7015
            // Redirty the range of cards...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7016
            _mut->mark_range(redirty_range);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7017
          } // ...else the setting of klass will dirty the card anyway.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7018
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7019
      DEBUG_ONLY(})
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7020
      return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7021
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7022
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7023
  scanOopsInOop(addr);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7024
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7025
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7026
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7027
// We take a break if we've been at this for a while,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7028
// so as to avoid monopolizing the locks involved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7029
void MarkFromRootsClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7030
  // First give up the locks, then yield, then re-lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7031
  // We should probably use a constructor/destructor idiom to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7032
  // do this unlock/lock or modify the MutexUnlocker class to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7033
  // serve our purpose. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7034
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7035
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7036
  assert_lock_strong(_bitMap->lock());
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7037
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7038
  _bitMap->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7039
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7040
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7041
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7042
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7043
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7044
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7045
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7046
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7047
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7048
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7049
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7050
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7051
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7052
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7053
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7054
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7055
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7056
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7057
  _bitMap->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7058
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7059
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7060
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7061
void MarkFromRootsClosure::scanOopsInOop(HeapWord* ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7062
  assert(_bitMap->isMarked(ptr), "expected bit to be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7063
  assert(_markStack->isEmpty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7064
         "should drain stack to limit stack usage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7065
  // 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
  7066
  oop obj = oop(ptr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7067
  // Ignore mark word in verification below, since we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7068
  // 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
  7069
  assert(obj->is_oop(true), "should be an oop");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7070
  assert(_finger <= ptr, "_finger runneth ahead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7071
  // 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
  7072
  _finger = ptr + obj->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7073
  assert(_finger > ptr, "we just incremented it above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7074
  // On large heaps, it may take us some time to get through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7075
  // the marking phase (especially if running iCMS). During
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7076
  // this time it's possible that a lot of mutations have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7077
  // accumulated in the card table and the mod union table --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7078
  // these mutation records are redundant until we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7079
  // actually traced into the corresponding card.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7080
  // Here, we check whether advancing the finger would make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7081
  // us cross into a new card, and if so clear corresponding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7082
  // cards in the MUT (preclean them in the card-table in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7083
  // future).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7084
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7085
  DEBUG_ONLY(if (!_verifying) {)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7086
    // The clean-on-enter optimization is disabled by default,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7087
    // until we fix 6178663.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7088
    if (CMSCleanOnEnter && (_finger > _threshold)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7089
      // [_threshold, _finger) represents the interval
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7090
      // of cards to be cleared  in MUT (or precleaned in card table).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7091
      // The set of cards to be cleared is all those that overlap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7092
      // with the interval [_threshold, _finger); note that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7093
      // _threshold is always kept card-aligned but _finger isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7094
      // always card-aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7095
      HeapWord* old_threshold = _threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7096
      assert(old_threshold == (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7097
              (intptr_t)old_threshold, CardTableModRefBS::card_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7098
             "_threshold should always be card-aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7099
      _threshold = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7100
                     (intptr_t)_finger, CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7101
      MemRegion mr(old_threshold, _threshold);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7102
      assert(!mr.is_empty(), "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7103
      assert(_span.contains(mr), "Should clear within span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7104
      // XXX When _finger crosses from old gen into perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7105
      // we may be doing unnecessary cleaning; do better in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7106
      // future by detecting that condition and clearing fewer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7107
      // MUT/CT entries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7108
      _mut->clear_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7109
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7110
  DEBUG_ONLY(})
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7111
  // Note: the finger doesn't advance while we drain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7112
  // the stack below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7113
  PushOrMarkClosure pushOrMarkClosure(_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7114
                                      _span, _bitMap, _markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7115
                                      _revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7116
                                      _finger, this);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7117
  bool res = _markStack->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7118
  assert(res, "Empty non-zero size stack should have space for single push");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7119
  while (!_markStack->isEmpty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7120
    oop new_oop = _markStack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7121
    // Skip verifying header mark word below because we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7122
    // running concurrent with mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7123
    assert(new_oop->is_oop(true), "Oops! expected to pop an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7124
    // now scan this oop's oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7125
    new_oop->oop_iterate(&pushOrMarkClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7126
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7127
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7128
  assert(_markStack->isEmpty(), "tautology, emphasizing post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7129
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7130
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7131
Par_MarkFromRootsClosure::Par_MarkFromRootsClosure(CMSConcMarkingTask* task,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7132
                       CMSCollector* collector, MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7133
                       CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7134
                       OopTaskQueue* work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7135
                       CMSMarkStack*  overflow_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7136
                       CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7137
                       bool should_yield):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7138
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7139
  _whole_span(collector->_span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7140
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7141
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7142
  _mut(&collector->_modUnionTable),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7143
  _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7144
  _overflow_stack(overflow_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7145
  _revisit_stack(revisit_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7146
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7147
  _skip_bits(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7148
  _task(task)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7149
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7150
  assert(_work_queue->size() == 0, "work_queue should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7151
  _finger = span.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7152
  _threshold = _finger;     // XXX Defer clear-on-enter optimization for now
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7153
  assert(_span.contains(_finger), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7154
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7155
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7156
// Should revisit to see if this should be restructured for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7157
// greater efficiency.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7158
bool Par_MarkFromRootsClosure::do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7159
  if (_skip_bits > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7160
    _skip_bits--;
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7161
    return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7162
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7163
  // convert offset into a HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7164
  HeapWord* addr = _bit_map->startWord() + offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7165
  assert(_bit_map->endWord() && addr < _bit_map->endWord(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7166
         "address out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7167
  assert(_bit_map->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7168
  if (_bit_map->isMarked(addr+1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7169
    // this is an allocated object that might not yet be initialized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7170
    assert(_skip_bits == 0, "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7171
    _skip_bits = 2;  // skip next two marked bits ("Printezis-marks")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7172
    oop p = oop(addr);
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  7173
    if (p->klass_or_null() == NULL || !p->is_parsable()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7174
      // in the case of Clean-on-Enter optimization, redirty card
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7175
      // and avoid clearing card by increasing  the threshold.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7176
      return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7177
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7178
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7179
  scan_oops_in_oop(addr);
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7180
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7181
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7182
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7183
void Par_MarkFromRootsClosure::scan_oops_in_oop(HeapWord* ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7184
  assert(_bit_map->isMarked(ptr), "expected bit to be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7185
  // Should we assert that our work queue is empty or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7186
  // below some drain limit?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7187
  assert(_work_queue->size() == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7188
         "should drain stack to limit stack usage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7189
  // 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
  7190
  oop obj = oop(ptr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7191
  // Ignore mark word in verification below, since we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7192
  // 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
  7193
  assert(obj->is_oop(true), "should be an oop");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7194
  assert(_finger <= ptr, "_finger runneth ahead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7195
  // 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
  7196
  _finger = ptr + obj->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7197
  assert(_finger > ptr, "we just incremented it above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7198
  // On large heaps, it may take us some time to get through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7199
  // the marking phase (especially if running iCMS). During
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7200
  // this time it's possible that a lot of mutations have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7201
  // accumulated in the card table and the mod union table --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7202
  // these mutation records are redundant until we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7203
  // actually traced into the corresponding card.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7204
  // Here, we check whether advancing the finger would make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7205
  // us cross into a new card, and if so clear corresponding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7206
  // cards in the MUT (preclean them in the card-table in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7207
  // future).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7208
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7209
  // The clean-on-enter optimization is disabled by default,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7210
  // until we fix 6178663.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7211
  if (CMSCleanOnEnter && (_finger > _threshold)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7212
    // [_threshold, _finger) represents the interval
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7213
    // of cards to be cleared  in MUT (or precleaned in card table).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7214
    // The set of cards to be cleared is all those that overlap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7215
    // with the interval [_threshold, _finger); note that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7216
    // _threshold is always kept card-aligned but _finger isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7217
    // always card-aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7218
    HeapWord* old_threshold = _threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7219
    assert(old_threshold == (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7220
            (intptr_t)old_threshold, CardTableModRefBS::card_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7221
           "_threshold should always be card-aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7222
    _threshold = (HeapWord*)round_to(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7223
                   (intptr_t)_finger, CardTableModRefBS::card_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7224
    MemRegion mr(old_threshold, _threshold);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7225
    assert(!mr.is_empty(), "Control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7226
    assert(_span.contains(mr), "Should clear within span"); // _whole_span ??
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7227
    // XXX When _finger crosses from old gen into perm gen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7228
    // we may be doing unnecessary cleaning; do better in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7229
    // future by detecting that condition and clearing fewer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7230
    // MUT/CT entries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7231
    _mut->clear_range(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7232
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7233
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7234
  // Note: the local finger doesn't advance while we drain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7235
  // the stack below, but the global finger sure can and will.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7236
  HeapWord** gfa = _task->global_finger_addr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7237
  Par_PushOrMarkClosure pushOrMarkClosure(_collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7238
                                      _span, _bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7239
                                      _work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7240
                                      _overflow_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7241
                                      _revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7242
                                      _finger,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7243
                                      gfa, this);
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7244
  bool res = _work_queue->push(obj);   // overflow could occur here
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7245
  assert(res, "Will hold once we use workqueues");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7246
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7247
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7248
    if (!_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7249
      // We emptied our work_queue; check if there's stuff that can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7250
      // be gotten from the overflow stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7251
      if (CMSConcMarkingTask::get_work_from_overflow_stack(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7252
            _overflow_stack, _work_queue)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7253
        do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7254
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7255
      } else {  // done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7256
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7257
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7258
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7259
    // Skip verifying header mark word below because we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7260
    // running concurrent with mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7261
    assert(new_oop->is_oop(true), "Oops! expected to pop an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7262
    // now scan this oop's oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7263
    new_oop->oop_iterate(&pushOrMarkClosure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7264
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7265
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7266
  assert(_work_queue->size() == 0, "tautology, emphasizing post-condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7267
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7268
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7269
// Yield in response to a request from VM Thread or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7270
// from mutators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7271
void Par_MarkFromRootsClosure::do_yield_work() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7272
  assert(_task != NULL, "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7273
  _task->yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7274
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7275
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7276
// A variant of the above used for verifying CMS marking work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7277
MarkFromRootsVerifyClosure::MarkFromRootsVerifyClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7278
                        MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7279
                        CMSBitMap* verification_bm, CMSBitMap* cms_bm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7280
                        CMSMarkStack*  mark_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7281
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7282
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7283
  _verification_bm(verification_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7284
  _cms_bm(cms_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7285
  _mark_stack(mark_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7286
  _pam_verify_closure(collector, span, verification_bm, cms_bm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7287
                      mark_stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7288
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7289
  assert(_mark_stack->isEmpty(), "stack should be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7290
  _finger = _verification_bm->startWord();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7291
  assert(_collector->_restart_addr == NULL, "Sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7292
  assert(_span.contains(_finger), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7293
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7295
void MarkFromRootsVerifyClosure::reset(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7296
  assert(_mark_stack->isEmpty(), "would cause duplicates on stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7297
  assert(_span.contains(addr), "Out of bounds _finger?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7298
  _finger = addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7299
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7300
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7301
// Should revisit to see if this should be restructured for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7302
// greater efficiency.
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7303
bool MarkFromRootsVerifyClosure::do_bit(size_t offset) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7304
  // convert offset into a HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7305
  HeapWord* addr = _verification_bm->startWord() + offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7306
  assert(_verification_bm->endWord() && addr < _verification_bm->endWord(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7307
         "address out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7308
  assert(_verification_bm->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7309
  assert(_cms_bm->isMarked(addr), "tautology");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7310
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7311
  assert(_mark_stack->isEmpty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7312
         "should drain stack to limit stack usage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7313
  // 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
  7314
  oop obj = oop(addr);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7315
  assert(obj->is_oop(), "should be an oop");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7316
  assert(_finger <= addr, "_finger runneth ahead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7317
  // 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
  7318
  _finger = addr + obj->size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7319
  assert(_finger > addr, "we just incremented it above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7320
  // Note: the finger doesn't advance while we drain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7321
  // the stack below.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7322
  bool res = _mark_stack->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7323
  assert(res, "Empty non-zero size stack should have space for single push");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7324
  while (!_mark_stack->isEmpty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7325
    oop new_oop = _mark_stack->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7326
    assert(new_oop->is_oop(), "Oops! expected to pop an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7327
    // now scan this oop's oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7328
    new_oop->oop_iterate(&_pam_verify_closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7329
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7330
  assert(_mark_stack->isEmpty(), "tautology, emphasizing post-condition");
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7331
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7332
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7333
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7334
PushAndMarkVerifyClosure::PushAndMarkVerifyClosure(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7335
  CMSCollector* collector, MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7336
  CMSBitMap* verification_bm, CMSBitMap* cms_bm,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7337
  CMSMarkStack*  mark_stack):
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7338
  OopClosure(collector->ref_processor()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7339
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7340
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7341
  _verification_bm(verification_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7342
  _cms_bm(cms_bm),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7343
  _mark_stack(mark_stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7344
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7345
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7346
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
  7347
void PushAndMarkVerifyClosure::do_oop(narrowOop* p) { PushAndMarkVerifyClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7348
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7349
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7350
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7351
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7352
void PushAndMarkVerifyClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7353
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7354
  HeapWord* ra = (HeapWord*)_mark_stack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7355
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7356
  _mark_stack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7357
  _mark_stack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7358
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7359
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7360
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
  7361
  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
  7362
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7363
  if (_span.contains(addr) && !_verification_bm->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7364
    // Oop lies in _span and isn't yet grey or black
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7365
    _verification_bm->mark(addr);            // now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7366
    if (!_cms_bm->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7367
      oop(addr)->print();
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7368
      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
  7369
                             addr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7370
      fatal("... aborting");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7371
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7372
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7373
    if (!_mark_stack->push(obj)) { // stack overflow
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7374
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7375
        gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7376
                               SIZE_FORMAT, _mark_stack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7377
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7378
      assert(_mark_stack->isFull(), "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7379
      handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7380
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7381
    // anything including and to the right of _finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7382
    // will be scanned as we iterate over the remainder of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7383
    // bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7384
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7385
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7386
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7387
PushOrMarkClosure::PushOrMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7388
                     MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7389
                     CMSBitMap* bitMap, CMSMarkStack*  markStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7390
                     CMSMarkStack*  revisitStack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7391
                     HeapWord* finger, MarkFromRootsClosure* parent) :
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7392
  KlassRememberingOopClosure(collector, collector->ref_processor(), revisitStack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7393
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7394
  _bitMap(bitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7395
  _markStack(markStack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7396
  _finger(finger),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7397
  _parent(parent)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7398
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7399
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7400
Par_PushOrMarkClosure::Par_PushOrMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7401
                     MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7402
                     CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7403
                     OopTaskQueue* work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7404
                     CMSMarkStack*  overflow_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7405
                     CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7406
                     HeapWord* finger,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7407
                     HeapWord** global_finger_addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7408
                     Par_MarkFromRootsClosure* parent) :
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7409
  Par_KlassRememberingOopClosure(collector,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7410
                            collector->ref_processor(),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7411
                            revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7412
  _whole_span(collector->_span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7413
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7414
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7415
  _work_queue(work_queue),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7416
  _overflow_stack(overflow_stack),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7417
  _finger(finger),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7418
  _global_finger_addr(global_finger_addr),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7419
  _parent(parent)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7420
{ }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7421
1372
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  7422
// Assumes thread-safe access by callers, who are
654bcf7839bc 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 991
diff changeset
  7423
// responsible for mutual exclusion.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7424
void CMSCollector::lower_restart_addr(HeapWord* low) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7425
  assert(_span.contains(low), "Out of bounds addr");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7426
  if (_restart_addr == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7427
    _restart_addr = low;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7428
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7429
    _restart_addr = MIN2(_restart_addr, low);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7430
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7431
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7432
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7433
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7434
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7435
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7436
void PushOrMarkClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7437
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7438
  HeapWord* ra = (HeapWord*)_markStack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7439
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7440
  _markStack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7441
  _markStack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7442
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7443
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7444
// Upon stack overflow, we discard (part of) the stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7445
// remembering the least address amongst those discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7446
// in CMSCollector's _restart_address.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7447
void Par_PushOrMarkClosure::handle_stack_overflow(HeapWord* lost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7448
  // 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
  7449
  // workers from interfering with the work done below.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7450
  MutexLockerEx ml(_overflow_stack->par_lock(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7451
                   Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7452
  // Remember the least grey address discarded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7453
  HeapWord* ra = (HeapWord*)_overflow_stack->least_value(lost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7454
  _collector->lower_restart_addr(ra);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7455
  _overflow_stack->reset();  // discard stack contents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7456
  _overflow_stack->expand(); // expand the stack if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7457
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7458
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7459
void PushOrMarkClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7460
  // 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
  7461
  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
  7462
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7463
  if (_span.contains(addr) && !_bitMap->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7464
    // Oop lies in _span and isn't yet grey or black
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7465
    _bitMap->mark(addr);            // now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7466
    if (addr < _finger) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7467
      // the bit map iteration has already either passed, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7468
      // sampled, this bit in the bit map; we'll need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7469
      // use the marking stack to scan this oop's oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7470
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7471
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7472
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7473
            _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7474
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7475
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7476
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7477
      )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7478
      if (simulate_overflow || !_markStack->push(obj)) { // stack overflow
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7479
        if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7480
          gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7481
                                 SIZE_FORMAT, _markStack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7482
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7483
        assert(simulate_overflow || _markStack->isFull(), "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7484
        handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7485
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7486
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7487
    // anything including and to the right of _finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7488
    // will be scanned as we iterate over the remainder of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7489
    // bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7490
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7491
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7492
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7493
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7494
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
  7495
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
  7496
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7497
void Par_PushOrMarkClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7498
  // 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
  7499
  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
  7500
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7501
  if (_whole_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7502
    // Oop lies in _span and isn't yet grey or black
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7503
    // We read the global_finger (volatile read) strictly after marking oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7504
    bool res = _bit_map->par_mark(addr);    // now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7505
    volatile HeapWord** gfa = (volatile HeapWord**)_global_finger_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7506
    // Should we push this marked oop on our stack?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7507
    // -- if someone else marked it, nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7508
    // -- if target oop is above global finger nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7509
    // -- if target oop is in chunk and above local finger
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7510
    //      then nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7511
    // -- else push on work queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7512
    if (   !res       // someone else marked it, they will deal with it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7513
        || (addr >= *gfa)  // will be scanned in a later task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7514
        || (_span.contains(addr) && addr >= _finger)) { // later in this chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7515
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7516
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7517
    // the bit map iteration has already either passed, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7518
    // sampled, this bit in the bit map; we'll need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7519
    // use the marking stack to scan this oop's oops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7520
    bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7521
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7522
      if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7523
          _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7524
        // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7525
        simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7526
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7527
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7528
    if (simulate_overflow ||
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7529
        !(_work_queue->push(obj) || _overflow_stack->par_push(obj))) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7530
      // stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7531
      if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7532
        gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7533
                               SIZE_FORMAT, _overflow_stack->capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7534
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7535
      // We cannot assert that the overflow stack is full because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7536
      // it may have been emptied since.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7537
      assert(simulate_overflow ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7538
             _work_queue->size() == _work_queue->max_elems(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7539
            "Else push should have succeeded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7540
      handle_stack_overflow(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7541
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7542
    do_yield_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7543
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7544
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7545
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7546
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
  7547
void Par_PushOrMarkClosure::do_oop(narrowOop* p) { Par_PushOrMarkClosure::do_oop_work(p); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7548
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7549
KlassRememberingOopClosure::KlassRememberingOopClosure(CMSCollector* collector,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7550
                                             ReferenceProcessor* rp,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7551
                                             CMSMarkStack* revisit_stack) :
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7552
  OopClosure(rp),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7553
  _collector(collector),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7554
  _revisit_stack(revisit_stack),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7555
  _should_remember_klasses(collector->should_unload_classes()) {}
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7556
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7557
PushAndMarkClosure::PushAndMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7558
                                       MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7559
                                       ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7560
                                       CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7561
                                       CMSBitMap* mod_union_table,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7562
                                       CMSMarkStack*  mark_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7563
                                       CMSMarkStack*  revisit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7564
                                       bool           concurrent_precleaning):
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7565
  KlassRememberingOopClosure(collector, rp, revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7566
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7567
  _bit_map(bit_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7568
  _mod_union_table(mod_union_table),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7569
  _mark_stack(mark_stack),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7570
  _concurrent_precleaning(concurrent_precleaning)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7571
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7572
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7573
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7574
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7575
// Grey object rescan during pre-cleaning and second checkpoint phases --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7576
// 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
  7577
void PushAndMarkClosure::do_oop(oop obj) {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7578
  // Ignore mark word verification. If during concurrent precleaning,
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7579
  // the object monitor may be locked. If during the checkpoint
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7580
  // 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
  7581
  // 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
  7582
  // the mark word may be NULL).
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 390
diff changeset
  7583
  assert(obj->is_oop_or_null(true /* ignore mark word */),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7584
         "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
  7585
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7586
  // Check if oop points into the CMS generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7587
  // and is not marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7588
  if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7589
    // a white object ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7590
    _bit_map->mark(addr);         // ... now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7591
    // push on the marking stack (grey set)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7592
    bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7593
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7594
      if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7595
          _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7596
        // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7597
        simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7598
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7599
    )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7600
    if (simulate_overflow || !_mark_stack->push(obj)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7601
      if (_concurrent_precleaning) {
991
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7602
         // During precleaning we can just dirty the appropriate card(s)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7603
         // 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
  7604
         // 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
  7605
         // 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
  7606
         // 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
  7607
         // dirty cards.
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7608
         // 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
  7609
         // 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
  7610
         // are required.
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7611
         if (obj->is_objArray()) {
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7612
           size_t sz = obj->size();
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7613
           HeapWord* end_card_addr = (HeapWord*)round_to(
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7614
                                        (intptr_t)(addr+sz), CardTableModRefBS::card_size);
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7615
           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
  7616
           assert(!redirty_range.is_empty(), "Arithmetical tautology");
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7617
           _mod_union_table->mark_range(redirty_range);
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7618
         } else {
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7619
           _mod_union_table->mark(addr);
5b25d0a7116f 6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
ysr
parents: 979
diff changeset
  7620
         }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7621
         _collector->_ser_pmc_preclean_ovflw++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7622
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7623
         // During the remark phase, we need to remember this oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7624
         // in the overflow list.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7625
         _collector->push_on_overflow_list(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7626
         _collector->_ser_pmc_remark_ovflw++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7627
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7628
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7629
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7630
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7631
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7632
Par_PushAndMarkClosure::Par_PushAndMarkClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7633
                                               MemRegion span,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7634
                                               ReferenceProcessor* rp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7635
                                               CMSBitMap* bit_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7636
                                               OopTaskQueue* work_queue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7637
                                               CMSMarkStack* revisit_stack):
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7638
  Par_KlassRememberingOopClosure(collector, rp, revisit_stack),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7639
  _span(span),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7640
  _bit_map(bit_map),
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7641
  _work_queue(work_queue)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7642
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7643
  assert(_ref_processor != NULL, "_ref_processor shouldn't be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7644
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7645
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7646
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
  7647
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
  7648
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7649
// Grey object rescan during second checkpoint phase --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7650
// the parallel version.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7651
void Par_PushAndMarkClosure::do_oop(oop obj) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7652
  // In the assert below, we ignore the mark word because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7653
  // this oop may point to an already visited object that is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7654
  // on the overflow stack (in which case the mark word has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7655
  // been hijacked for chaining into the overflow stack --
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7656
  // if this is the last object in the overflow stack then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7657
  // its mark word will be NULL). Because this object may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7658
  // have been subsequently popped off the global overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7659
  // stack, and the mark word possibly restored to the prototypical
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7660
  // value, by the time we get to examined this failing assert in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7661
  // the debugger, is_oop_or_null(false) may subsequently start
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7662
  // to hold.
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7663
  assert(obj->is_oop_or_null(true),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7664
         "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
  7665
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7666
  // Check if oop points into the CMS generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7667
  // and is not marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7668
  if (_span.contains(addr) && !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7669
    // a white object ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7670
    // If we manage to "claim" the object, by being the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7671
    // first thread to mark it, then we push it on our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7672
    // marking stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7673
    if (_bit_map->par_mark(addr)) {     // ... now grey
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7674
      // push on work queue (grey set)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7675
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7676
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7677
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7678
            _collector->par_simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7679
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7680
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7681
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7682
      )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7683
      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
  7684
        _collector->par_push_on_overflow_list(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7685
        _collector->_par_pmc_remark_ovflw++; //  imprecise OK: no need to CAS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7686
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7687
    } // Else, some other thread got there first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7688
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7689
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7690
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  7691
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
  7692
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
  7693
3696
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7694
void PushAndMarkClosure::remember_mdo(DataLayout* v) {
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7695
  // TBD
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7696
}
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7697
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7698
void Par_PushAndMarkClosure::remember_mdo(DataLayout* v) {
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7699
  // TBD
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7700
}
9e5d9b5e1049 4957990: Perm heap bloat in JVM
ysr
parents: 3690
diff changeset
  7701
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7702
void CMSPrecleanRefsYieldClosure::do_yield_work() {
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  7703
  DEBUG_ONLY(RememberKlassesChecker mux(false);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7704
  Mutex* bml = _collector->bitMapLock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7705
  assert_lock_strong(bml);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7706
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7707
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7708
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7709
  bml->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7710
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7711
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7712
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7713
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7714
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7715
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7716
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7717
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7718
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7719
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7720
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7721
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7722
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7723
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7724
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7725
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7726
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7727
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7728
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7729
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7730
  bml->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7731
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7732
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7733
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7734
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7735
bool CMSPrecleanRefsYieldClosure::should_return() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7736
  if (ConcurrentMarkSweepThread::should_yield()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7737
    do_yield_work();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7738
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7739
  return _collector->foregroundGCIsActive();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7740
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7741
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7742
void MarkFromDirtyCardsClosure::do_MemRegion(MemRegion mr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7743
  assert(((size_t)mr.start())%CardTableModRefBS::card_size_in_words == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7744
         "mr should be aligned to start at a card boundary");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7745
  // We'd like to assert:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7746
  // assert(mr.word_size()%CardTableModRefBS::card_size_in_words == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7747
  //        "mr should be a range of cards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7748
  // However, that would be too strong in one case -- the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7749
  // partition ends at _unallocated_block which, in general, can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7750
  // an arbitrary boundary, not necessarily card aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7751
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7752
    _num_dirty_cards +=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7753
         mr.word_size()/CardTableModRefBS::card_size_in_words;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7754
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7755
  _space->object_iterate_mem(mr, &_scan_cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7756
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7757
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7758
SweepClosure::SweepClosure(CMSCollector* collector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7759
                           ConcurrentMarkSweepGeneration* g,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7760
                           CMSBitMap* bitMap, bool should_yield) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7761
  _collector(collector),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7762
  _g(g),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7763
  _sp(g->cmsSpace()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7764
  _limit(_sp->sweep_limit()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7765
  _freelistLock(_sp->freelistLock()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7766
  _bitMap(bitMap),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7767
  _yield(should_yield),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7768
  _inFreeRange(false),           // No free range at beginning of sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7769
  _freeRangeInFreeLists(false),  // No free range at beginning of sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7770
  _lastFreeRangeCoalesced(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7771
  _freeFinger(g->used_region().start())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7772
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7773
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7774
    _numObjectsFreed = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7775
    _numWordsFreed   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7776
    _numObjectsLive = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7777
    _numWordsLive = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7778
    _numObjectsAlreadyFree = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7779
    _numWordsAlreadyFree = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7780
    _last_fc = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7781
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7782
    _sp->initializeIndexedFreeListArrayReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7783
    _sp->dictionary()->initializeDictReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7784
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7785
  assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7786
         "sweep _limit out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7787
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7788
    gclog_or_tty->print("\n====================\nStarting new sweep\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7789
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7790
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7791
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7792
// We need this destructor to reclaim any space at the end
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7793
// of the space, which do_blk below may not have added back to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7794
// the free lists. [basically dealing with the "fringe effect"]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7795
SweepClosure::~SweepClosure() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7796
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7797
  // this should be treated as the end of a free run if any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7798
  // The current free range should be returned to the free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7799
  // as one coalesced chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7800
  if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7801
    flushCurFreeChunk(freeFinger(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7802
      pointer_delta(_limit, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7803
    assert(freeFinger() < _limit, "the finger pointeth off base");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7804
    if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7805
      gclog_or_tty->print("destructor:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7806
      gclog_or_tty->print("Sweep:put_free_blk 0x%x ("SIZE_FORMAT") "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7807
                 "[coalesced:"SIZE_FORMAT"]\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7808
                 freeFinger(), pointer_delta(_limit, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7809
                 lastFreeRangeCoalesced());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7810
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7811
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7812
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7813
    if (Verbose && PrintGC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7814
      gclog_or_tty->print("Collected "SIZE_FORMAT" objects, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7815
                          SIZE_FORMAT " bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7816
                 _numObjectsFreed, _numWordsFreed*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7817
      gclog_or_tty->print_cr("\nLive "SIZE_FORMAT" objects,  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7818
                             SIZE_FORMAT" bytes  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7819
        "Already free "SIZE_FORMAT" objects, "SIZE_FORMAT" bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7820
        _numObjectsLive, _numWordsLive*sizeof(HeapWord),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7821
        _numObjectsAlreadyFree, _numWordsAlreadyFree*sizeof(HeapWord));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7822
      size_t totalBytes = (_numWordsFreed + _numWordsLive + _numWordsAlreadyFree) *
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7823
        sizeof(HeapWord);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7824
      gclog_or_tty->print_cr("Total sweep: "SIZE_FORMAT" bytes", totalBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7825
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7826
      if (PrintCMSStatistics && CMSVerifyReturnedBytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7827
        size_t indexListReturnedBytes = _sp->sumIndexedFreeListArrayReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7828
        size_t dictReturnedBytes = _sp->dictionary()->sumDictReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7829
        size_t returnedBytes = indexListReturnedBytes + dictReturnedBytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7830
        gclog_or_tty->print("Returned "SIZE_FORMAT" bytes", returnedBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7831
        gclog_or_tty->print("   Indexed List Returned "SIZE_FORMAT" bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7832
          indexListReturnedBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7833
        gclog_or_tty->print_cr("        Dictionary Returned "SIZE_FORMAT" bytes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7834
          dictReturnedBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7835
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7836
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7837
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7838
  // Now, in debug mode, just null out the sweep_limit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7839
  NOT_PRODUCT(_sp->clear_sweep_limit();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7840
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7841
    gclog_or_tty->print("end of sweep\n================\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7842
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7843
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7844
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7845
void SweepClosure::initialize_free_range(HeapWord* freeFinger,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7846
    bool freeRangeInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7847
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7848
    gclog_or_tty->print("---- Start free range 0x%x with free block [%d] (%d)\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7849
               freeFinger, _sp->block_size(freeFinger),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7850
               freeRangeInFreeLists);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7851
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7852
  assert(!inFreeRange(), "Trampling existing free range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7853
  set_inFreeRange(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7854
  set_lastFreeRangeCoalesced(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7855
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7856
  set_freeFinger(freeFinger);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7857
  set_freeRangeInFreeLists(freeRangeInFreeLists);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7858
  if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7859
    if (freeRangeInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7860
      FreeChunk* fc = (FreeChunk*) freeFinger;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7861
      assert(fc->isFree(), "A chunk on the free list should be free.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7862
      assert(fc->size() > 0, "Free range should have a size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7863
      assert(_sp->verifyChunkInFreeLists(fc), "Chunk is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7864
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7865
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7866
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7867
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7868
// Note that the sweeper runs concurrently with mutators. Thus,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7869
// it is possible for direct allocation in this generation to happen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7870
// in the middle of the sweep. Note that the sweeper also coalesces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7871
// contiguous free blocks. Thus, unless the sweeper and the allocator
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7872
// synchronize appropriately freshly allocated blocks may get swept up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7873
// This is accomplished by the sweeper locking the free lists while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7874
// it is sweeping. Thus blocks that are determined to be free are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7875
// indeed free. There is however one additional complication:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7876
// blocks that have been allocated since the final checkpoint and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7877
// mark, will not have been marked and so would be treated as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7878
// unreachable and swept up. To prevent this, the allocator marks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7879
// the bit map when allocating during the sweep phase. This leads,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7880
// however, to a further complication -- objects may have been allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7881
// but not yet initialized -- in the sense that the header isn't yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7882
// installed. The sweeper can not then determine the size of the block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7883
// in order to skip over it. To deal with this case, we use a technique
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7884
// (due to Printezis) to encode such uninitialized block sizes in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7885
// bit map. Since the bit map uses a bit per every HeapWord, but the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7886
// CMS generation has a minimum object size of 3 HeapWords, it follows
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7887
// that "normal marks" won't be adjacent in the bit map (there will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7888
// always be at least two 0 bits between successive 1 bits). We make use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7889
// of these "unused" bits to represent uninitialized blocks -- the bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7890
// corresponding to the start of the uninitialized object and the next
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7891
// bit are both set. Finally, a 1 bit marks the end of the object that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7892
// started with the two consecutive 1 bits to indicate its potentially
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7893
// uninitialized state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7894
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7895
size_t SweepClosure::do_blk_careful(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7896
  FreeChunk* fc = (FreeChunk*)addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7897
  size_t res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7898
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7899
  // check if we are done sweepinrg
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7900
  if (addr == _limit) { // we have swept up to the limit, do nothing more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7901
    assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7902
           "sweep _limit out of bounds");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7903
    // help the closure application finish
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7904
    return pointer_delta(_sp->end(), _limit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7905
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7906
  assert(addr <= _limit, "sweep invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7907
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7908
  // check if we should yield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7909
  do_yield_check(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7910
  if (fc->isFree()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7911
    // Chunk that is already free
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7912
    res = fc->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7913
    doAlreadyFreeChunk(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7914
    debug_only(_sp->verifyFreeLists());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7915
    assert(res == fc->size(), "Don't expect the size to change");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7916
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7917
      _numObjectsAlreadyFree++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7918
      _numWordsAlreadyFree += res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7919
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7920
    NOT_PRODUCT(_last_fc = fc;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7921
  } else if (!_bitMap->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7922
    // Chunk is fresh garbage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7923
    res = doGarbageChunk(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7924
    debug_only(_sp->verifyFreeLists());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7925
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7926
      _numObjectsFreed++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7927
      _numWordsFreed += res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7928
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7929
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7930
    // Chunk that is alive.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7931
    res = doLiveChunk(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7932
    debug_only(_sp->verifyFreeLists());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7933
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7934
        _numObjectsLive++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7935
        _numWordsLive += res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7936
    )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7937
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7938
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7939
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7940
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7941
// For the smart allocation, record following
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7942
//  split deaths - a free chunk is removed from its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7943
//      it is being split into two or more chunks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7944
//  split birth - a free chunk is being added to its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7945
//      a larger free chunk has been split and resulted in this free chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7946
//  coal death - a free chunk is being removed from its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7947
//      it is being coalesced into a large free chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7948
//  coal birth - a free chunk is being added to its free list because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7949
//      it was created when two or more free chunks where coalesced into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7950
//      this free chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7951
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7952
// These statistics are used to determine the desired number of free
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7953
// chunks of a given size.  The desired number is chosen to be relative
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7954
// to the end of a CMS sweep.  The desired number at the end of a sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7955
// is the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7956
//      count-at-end-of-previous-sweep (an amount that was enough)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7957
//              - count-at-beginning-of-current-sweep  (the excess)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7958
//              + split-births  (gains in this size during interval)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7959
//              - split-deaths  (demands on this size during interval)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7960
// where the interval is from the end of one sweep to the end of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7961
// next.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7962
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7963
// When sweeping the sweeper maintains an accumulated chunk which is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7964
// the chunk that is made up of chunks that have been coalesced.  That
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7965
// will be termed the left-hand chunk.  A new chunk of garbage that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7966
// is being considered for coalescing will be referred to as the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7967
// right-hand chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7968
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7969
// When making a decision on whether to coalesce a right-hand chunk with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7970
// the current left-hand chunk, the current count vs. the desired count
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7971
// of the left-hand chunk is considered.  Also if the right-hand chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7972
// is near the large chunk at the end of the heap (see
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7973
// ConcurrentMarkSweepGeneration::isNearLargestChunk()), then the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7974
// left-hand chunk is coalesced.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7975
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7976
// When making a decision about whether to split a chunk, the desired count
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7977
// vs. the current count of the candidate to be split is also considered.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7978
// If the candidate is underpopulated (currently fewer chunks than desired)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7979
// a chunk of an overpopulated (currently more chunks than desired) size may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7980
// be chosen.  The "hint" associated with a free list, if non-null, points
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7981
// to a free list which may be overpopulated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7982
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7983
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7984
void SweepClosure::doAlreadyFreeChunk(FreeChunk* fc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7985
  size_t size = fc->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7986
  // Chunks that cannot be coalesced are not in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7987
  // free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7988
  if (CMSTestInFreeList && !fc->cantCoalesce()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7989
    assert(_sp->verifyChunkInFreeLists(fc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7990
      "free chunk should be in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7991
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7992
  // a chunk that is already free, should not have been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7993
  // marked in the bit map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7994
  HeapWord* addr = (HeapWord*) fc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7995
  assert(!_bitMap->isMarked(addr), "free chunk should be unmarked");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7996
  // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7997
  // addr and purported end of this block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7998
  _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  7999
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8000
  // Some chunks cannot be coalesced in under any circumstances.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8001
  // See the definition of cantCoalesce().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8002
  if (!fc->cantCoalesce()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8003
    // This chunk can potentially be coalesced.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8004
    if (_sp->adaptive_freelists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8005
      // All the work is done in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8006
      doPostIsFreeOrGarbageChunk(fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8007
    } else {  // Not adaptive free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8008
      // this is a free chunk that can potentially be coalesced by the sweeper;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8009
      if (!inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8010
        // if the next chunk is a free block that can't be coalesced
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8011
        // it doesn't make sense to remove this chunk from the free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8012
        FreeChunk* nextChunk = (FreeChunk*)(addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8013
        assert((HeapWord*)nextChunk <= _limit, "sweep invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8014
        if ((HeapWord*)nextChunk < _limit  &&    // there's a next chunk...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8015
            nextChunk->isFree()    &&            // which is free...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8016
            nextChunk->cantCoalesce()) {         // ... but cant be coalesced
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8017
          // nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8018
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8019
          // Potentially the start of a new free range:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8020
          // Don't eagerly remove it from the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8021
          // No need to remove it if it will just be put
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8022
          // back again.  (Also from a pragmatic point of view
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8023
          // if it is a free block in a region that is beyond
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8024
          // any allocated blocks, an assertion will fail)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8025
          // Remember the start of a free run.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8026
          initialize_free_range(addr, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8027
          // end - can coalesce with next chunk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8028
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8029
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8030
        // the midst of a free range, we are coalescing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8031
        debug_only(record_free_block_coalesced(fc);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8032
        if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8033
          gclog_or_tty->print("  -- pick up free block 0x%x (%d)\n", fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8034
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8035
        // remove it from the free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8036
        _sp->removeFreeChunkFromFreeLists(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8037
        set_lastFreeRangeCoalesced(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8038
        // If the chunk is being coalesced and the current free range is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8039
        // in the free lists, remove the current free range so that it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8040
        // will be returned to the free lists in its entirety - all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8041
        // the coalesced pieces included.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8042
        if (freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8043
          FreeChunk* ffc = (FreeChunk*) freeFinger();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8044
          assert(ffc->size() == pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8045
            "Size of free range is inconsistent with chunk size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8046
          if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8047
            assert(_sp->verifyChunkInFreeLists(ffc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8048
              "free range is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8049
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8050
          _sp->removeFreeChunkFromFreeLists(ffc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8051
          set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8052
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8053
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8054
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8055
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8056
    // Code path common to both original and adaptive free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8057
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8058
    // cant coalesce with previous block; this should be treated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8059
    // as the end of a free run if any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8060
    if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8061
      // we kicked some butt; time to pick up the garbage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8062
      assert(freeFinger() < addr, "the finger pointeth off base");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8063
      flushCurFreeChunk(freeFinger(), pointer_delta(addr, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8064
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8065
    // else, nothing to do, just continue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8066
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8067
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8068
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8069
size_t SweepClosure::doGarbageChunk(FreeChunk* fc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8070
  // This is a chunk of garbage.  It is not in any free list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8071
  // Add it to a free list or let it possibly be coalesced into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8072
  // a larger chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8073
  HeapWord* addr = (HeapWord*) fc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8074
  size_t size = CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8075
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8076
  if (_sp->adaptive_freelists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8077
    // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8078
    // addr and purported end of just dead object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8079
    _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8080
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8081
    doPostIsFreeOrGarbageChunk(fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8082
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8083
    if (!inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8084
      // start of a new free range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8085
      assert(size > 0, "A free range should have a size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8086
      initialize_free_range(addr, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8087
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8088
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8089
      // this will be swept up when we hit the end of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8090
      // free range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8091
      if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8092
        gclog_or_tty->print("  -- pick up garbage 0x%x (%d) \n", fc, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8093
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8094
      // If the chunk is being coalesced and the current free range is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8095
      // in the free lists, remove the current free range so that it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8096
      // will be returned to the free lists in its entirety - all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8097
      // the coalesced pieces included.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8098
      if (freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8099
        FreeChunk* ffc = (FreeChunk*)freeFinger();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8100
        assert(ffc->size() == pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8101
          "Size of free range is inconsistent with chunk size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8102
        if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8103
          assert(_sp->verifyChunkInFreeLists(ffc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8104
            "free range is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8105
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8106
        _sp->removeFreeChunkFromFreeLists(ffc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8107
        set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8108
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8109
      set_lastFreeRangeCoalesced(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8110
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8111
    // this will be swept up when we hit the end of the free range
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8112
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8113
    // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8114
    // addr and purported end of just dead object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8115
    _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8116
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8117
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8118
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8119
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8120
size_t SweepClosure::doLiveChunk(FreeChunk* fc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8121
  HeapWord* addr = (HeapWord*) fc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8122
  // The sweeper has just found a live object. Return any accumulated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8123
  // left hand chunk to the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8124
  if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8125
    if (_sp->adaptive_freelists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8126
      flushCurFreeChunk(freeFinger(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8127
                        pointer_delta(addr, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8128
    } else { // not adaptive freelists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8129
      set_inFreeRange(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8130
      // Add the free range back to the free list if it is not already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8131
      // there.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8132
      if (!freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8133
        assert(freeFinger() < addr, "the finger pointeth off base");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8134
        if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8135
          gclog_or_tty->print("Sweep:put_free_blk 0x%x (%d) "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8136
            "[coalesced:%d]\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8137
            freeFinger(), pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8138
            lastFreeRangeCoalesced());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8139
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8140
        _sp->addChunkAndRepairOffsetTable(freeFinger(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8141
          pointer_delta(addr, freeFinger()), lastFreeRangeCoalesced());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8142
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8143
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8144
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8145
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8146
  // Common code path for original and adaptive free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8147
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8148
  // this object is live: we'd normally expect this to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8149
  // an oop, and like to assert the following:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8150
  // assert(oop(addr)->is_oop(), "live block should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8151
  // However, as we commented above, this may be an object whose
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8152
  // header hasn't yet been initialized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8153
  size_t size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8154
  assert(_bitMap->isMarked(addr), "Tautology for this control point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8155
  if (_bitMap->isMarked(addr + 1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8156
    // Determine the size from the bit map, rather than trying to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8157
    // compute it from the object header.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8158
    HeapWord* nextOneAddr = _bitMap->getNextMarkedWordAddress(addr + 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8159
    size = pointer_delta(nextOneAddr + 1, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8160
    assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8161
           "alignment problem");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8162
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8163
    #ifdef DEBUG
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  8164
      if (oop(addr)->klass_or_null() != NULL &&
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  8165
          (   !_collector->should_unload_classes()
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8166
           || (oop(addr)->is_parsable()) &&
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8167
               oop(addr)->is_conc_safe())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8168
        // Ignore mark word because we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8169
        assert(oop(addr)->is_oop(true), "live block should be an oop");
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8170
        // is_conc_safe is checked before performing this assertion
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8171
        // because an object that is not is_conc_safe may yet have
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8172
        // the return from size() correct.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8173
        assert(size ==
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8174
               CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8175
               "P-mark and computed size do not agree");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8176
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8177
    #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8179
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8180
    // This should be an initialized object that's alive.
613
2aa2b913106c 6687581: Make CMS work with compressed oops
coleenp
parents: 390
diff changeset
  8181
    assert(oop(addr)->klass_or_null() != NULL &&
341
6578aad59716 6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction
ysr
parents: 182
diff changeset
  8182
           (!_collector->should_unload_classes()
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8183
            || oop(addr)->is_parsable()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8184
           "Should be an initialized object");
1894
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8185
    // Note that there are objects used during class redefinition
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8186
    // (e.g., merge_cp in VM_RedefineClasses::merge_cp_and_rewrite()
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8187
    // which are discarded with their is_conc_safe state still
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8188
    // false.  These object may be floating garbage so may be
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8189
    // seen here.  If they are floating garbage their size
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8190
    // should be attainable from their klass.  Do not that
5c343868d071 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 1893
diff changeset
  8191
    // is_conc_safe() is true for oop(addr).
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8192
    // Ignore mark word because we are running concurrent with mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8193
    assert(oop(addr)->is_oop(true), "live block should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8194
    // Verify that the bit map has no bits marked between
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8195
    // addr and purported end of this block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8196
    size = CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8197
    assert(size >= 3, "Necessary for Printezis marks to work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8198
    assert(!_bitMap->isMarked(addr+1), "Tautology for this control point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8199
    DEBUG_ONLY(_bitMap->verifyNoOneBitsInRange(addr+2, addr+size);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8200
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8201
  return size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8202
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8203
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8204
void SweepClosure::doPostIsFreeOrGarbageChunk(FreeChunk* fc,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8205
                                            size_t chunkSize) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8206
  // doPostIsFreeOrGarbageChunk() should only be called in the smart allocation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8207
  // scheme.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8208
  bool fcInFreeLists = fc->isFree();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8209
  assert(_sp->adaptive_freelists(), "Should only be used in this case.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8210
  assert((HeapWord*)fc <= _limit, "sweep invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8211
  if (CMSTestInFreeList && fcInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8212
    assert(_sp->verifyChunkInFreeLists(fc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8213
      "free chunk is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8214
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8215
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8216
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8217
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8218
    gclog_or_tty->print_cr("  -- pick up another chunk at 0x%x (%d)", fc, chunkSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8219
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8220
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8221
  HeapWord* addr = (HeapWord*) fc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8222
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8223
  bool coalesce;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8224
  size_t left  = pointer_delta(addr, freeFinger());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8225
  size_t right = chunkSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8226
  switch (FLSCoalescePolicy) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8227
    // numeric value forms a coalition aggressiveness metric
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8228
    case 0:  { // never coalesce
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8229
      coalesce = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8230
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8231
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8232
    case 1: { // coalesce if left & right chunks on overpopulated lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8233
      coalesce = _sp->coalOverPopulated(left) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8234
                 _sp->coalOverPopulated(right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8235
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8236
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8237
    case 2: { // coalesce if left chunk on overpopulated list (default)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8238
      coalesce = _sp->coalOverPopulated(left);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8239
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8240
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8241
    case 3: { // coalesce if left OR right chunk on overpopulated list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8242
      coalesce = _sp->coalOverPopulated(left) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8243
                 _sp->coalOverPopulated(right);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8244
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8245
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8246
    case 4: { // always coalesce
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8247
      coalesce = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8248
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8249
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8250
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8251
     ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8252
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8253
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8254
  // Should the current free range be coalesced?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8255
  // If the chunk is in a free range and either we decided to coalesce above
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8256
  // or the chunk is near the large block at the end of the heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8257
  // (isNearLargestChunk() returns true), then coalesce this chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8258
  bool doCoalesce = inFreeRange() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8259
    (coalesce || _g->isNearLargestChunk((HeapWord*)fc));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8260
  if (doCoalesce) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8261
    // Coalesce the current free range on the left with the new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8262
    // chunk on the right.  If either is on a free list,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8263
    // it must be removed from the list and stashed in the closure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8264
    if (freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8265
      FreeChunk* ffc = (FreeChunk*)freeFinger();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8266
      assert(ffc->size() == pointer_delta(addr, freeFinger()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8267
        "Size of free range is inconsistent with chunk size.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8268
      if (CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8269
        assert(_sp->verifyChunkInFreeLists(ffc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8270
          "Chunk is not in free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8271
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8272
      _sp->coalDeath(ffc->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8273
      _sp->removeFreeChunkFromFreeLists(ffc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8274
      set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8275
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8276
    if (fcInFreeLists) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8277
      _sp->coalDeath(chunkSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8278
      assert(fc->size() == chunkSize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8279
        "The chunk has the wrong size or is not in the free lists");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8280
      _sp->removeFreeChunkFromFreeLists(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8281
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8282
    set_lastFreeRangeCoalesced(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8283
  } else {  // not in a free range and/or should not coalesce
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8284
    // Return the current free range and start a new one.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8285
    if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8286
      // In a free range but cannot coalesce with the right hand chunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8287
      // Put the current free range into the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8288
      flushCurFreeChunk(freeFinger(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8289
        pointer_delta(addr, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8290
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8291
    // Set up for new free range.  Pass along whether the right hand
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8292
    // chunk is in the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8293
    initialize_free_range((HeapWord*)fc, fcInFreeLists);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8294
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8295
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8296
void SweepClosure::flushCurFreeChunk(HeapWord* chunk, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8297
  assert(inFreeRange(), "Should only be called if currently in a free range.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8298
  assert(size > 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8299
    "A zero sized chunk cannot be added to the free lists.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8300
  if (!freeRangeInFreeLists()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8301
    if(CMSTestInFreeList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8302
      FreeChunk* fc = (FreeChunk*) chunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8303
      fc->setSize(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8304
      assert(!_sp->verifyChunkInFreeLists(fc),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8305
        "chunk should not be in free lists yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8306
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8307
    if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8308
      gclog_or_tty->print_cr(" -- add free block 0x%x (%d) to free lists",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8309
                    chunk, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8310
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8311
    // A new free range is going to be starting.  The current
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8312
    // free range has not been added to the free lists yet or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8313
    // was removed so add it back.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8314
    // If the current free range was coalesced, then the death
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8315
    // of the free range was recorded.  Record a birth now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8316
    if (lastFreeRangeCoalesced()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8317
      _sp->coalBirth(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8318
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8319
    _sp->addChunkAndRepairOffsetTable(chunk, size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8320
            lastFreeRangeCoalesced());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8321
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8322
  set_inFreeRange(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8323
  set_freeRangeInFreeLists(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8324
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8325
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8326
// We take a break if we've been at this for a while,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8327
// so as to avoid monopolizing the locks involved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8328
void SweepClosure::do_yield_work(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8329
  // Return current free chunk being used for coalescing (if any)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8330
  // to the appropriate freelist.  After yielding, the next
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8331
  // free block encountered will start a coalescing range of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8332
  // free blocks.  If the next free block is adjacent to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8333
  // chunk just flushed, they will need to wait for the next
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8334
  // sweep to be coalesced.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8335
  if (inFreeRange()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8336
    flushCurFreeChunk(freeFinger(), pointer_delta(addr, freeFinger()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8337
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8338
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8339
  // First give up the locks, then yield, then re-lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8340
  // We should probably use a constructor/destructor idiom to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8341
  // do this unlock/lock or modify the MutexUnlocker class to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8342
  // serve our purpose. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8343
  assert_lock_strong(_bitMap->lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8344
  assert_lock_strong(_freelistLock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8345
  assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8346
         "CMS thread should hold CMS token");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8347
  _bitMap->lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8348
  _freelistLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8349
  ConcurrentMarkSweepThread::desynchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8350
  ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8351
  _collector->stopTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8352
  GCPauseTimer p(_collector->size_policy()->concurrent_timer_ptr());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8353
  if (PrintCMSStatistics != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8354
    _collector->incrementYields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8355
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8356
  _collector->icms_wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8357
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8358
  // See the comment in coordinator_yield()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8359
  for (unsigned i = 0; i < CMSYieldSleepCount &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8360
                       ConcurrentMarkSweepThread::should_yield() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8361
                       !CMSCollector::foregroundGCIsActive(); ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8362
    os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8363
    ConcurrentMarkSweepThread::acknowledge_yield_request();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8364
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8365
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8366
  ConcurrentMarkSweepThread::synchronize(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8367
  _freelistLock->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8368
  _bitMap->lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8369
  _collector->startTimer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8370
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8371
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8372
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8373
// This is actually very useful in a product build if it can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8374
// be called from the debugger.  Compile it into the product
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8375
// as needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8376
bool debug_verifyChunkInFreeLists(FreeChunk* fc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8377
  return debug_cms_space->verifyChunkInFreeLists(fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8378
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8379
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8380
void SweepClosure::record_free_block_coalesced(FreeChunk* fc) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8381
  if (CMSTraceSweeper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8382
    gclog_or_tty->print("Sweep:coal_free_blk 0x%x (%d)\n", fc, fc->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8383
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8384
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8385
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8386
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8387
// CMSIsAliveClosure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8388
bool CMSIsAliveClosure::do_object_b(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8389
  HeapWord* addr = (HeapWord*)obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8390
  return addr != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8391
         (!_span.contains(addr) || _bit_map->isMarked(addr));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8392
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8393
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8394
CMSKeepAliveClosure::CMSKeepAliveClosure( CMSCollector* collector,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8395
                      MemRegion span,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8396
                      CMSBitMap* bit_map, CMSMarkStack* mark_stack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8397
                      CMSMarkStack* revisit_stack, bool cpc):
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8398
  KlassRememberingOopClosure(collector, NULL, revisit_stack),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8399
  _span(span),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8400
  _bit_map(bit_map),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8401
  _mark_stack(mark_stack),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8402
  _concurrent_precleaning(cpc) {
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8403
  assert(!_span.is_empty(), "Empty span could spell trouble");
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8404
}
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8405
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8406
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8407
// CMSKeepAliveClosure: the serial version
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8408
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
  8409
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8410
  if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8411
      !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8412
    _bit_map->mark(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8413
    bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8414
    NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8415
      if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8416
          _collector->simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8417
        // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8418
        simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8419
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8420
    )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8421
    if (simulate_overflow || !_mark_stack->push(obj)) {
1605
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8422
      if (_concurrent_precleaning) {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8423
        // 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
  8424
        // phase deal with it.
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8425
        assert(_collector->overflow_list_is_empty(), "Error");
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8426
        // 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
  8427
        // 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
  8428
        // 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
  8429
        // table.
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8430
        if (obj->is_objArray()) {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8431
          size_t sz = obj->size();
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8432
          HeapWord* end_card_addr =
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8433
            (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
  8434
          MemRegion redirty_range = MemRegion(addr, end_card_addr);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8435
          assert(!redirty_range.is_empty(), "Arithmetical tautology");
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8436
          _collector->_modUnionTable.mark_range(redirty_range);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8437
        } else {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8438
          _collector->_modUnionTable.mark(addr);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8439
        }
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8440
        _collector->_ser_kac_preclean_ovflw++;
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8441
      } else {
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8442
        _collector->push_on_overflow_list(obj);
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8443
        _collector->_ser_kac_ovflw++;
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8444
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8445
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8446
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8447
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8448
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8449
void CMSKeepAliveClosure::do_oop(oop* 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
  8450
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
  8451
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8452
// CMSParKeepAliveClosure: a parallel version of the above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8453
// The work queues are private to each closure (thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8454
// 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
  8455
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
  8456
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8457
  if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8458
      !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8459
    // In general, during recursive tracing, several threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8460
    // may be concurrently getting here; the first one to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8461
    // "tag" it, claims it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8462
    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
  8463
      bool res = _work_queue->push(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8464
      assert(res, "Low water mark should be much less than capacity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8465
      // Do a recursive trim in the hope that this will keep
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8466
      // stack usage lower, but leave some oops for potential stealers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8467
      trim_queue(_low_water_mark);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8468
    } // Else, another thread got there first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8469
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8470
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8471
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8472
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
  8473
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
  8474
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8475
void CMSParKeepAliveClosure::trim_queue(uint max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8476
  while (_work_queue->size() > max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8477
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8478
    if (_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8479
      assert(new_oop != NULL && new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8480
      assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8481
             "no white objects on this stack!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8482
      assert(_span.contains((HeapWord*)new_oop), "Out of bounds oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8483
      // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8484
      // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8485
      new_oop->oop_iterate(&_mark_and_push);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8486
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8487
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8488
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8489
3690
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8490
CMSInnerParMarkAndPushClosure::CMSInnerParMarkAndPushClosure(
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8491
                                CMSCollector* collector,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8492
                                MemRegion span, CMSBitMap* bit_map,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8493
                                CMSMarkStack* revisit_stack,
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8494
                                OopTaskQueue* work_queue):
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8495
  Par_KlassRememberingOopClosure(collector, NULL, revisit_stack),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8496
  _span(span),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8497
  _bit_map(bit_map),
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8498
  _work_queue(work_queue) { }
dba50b88bd50 6798898: CMS: bugs related to class unloading
jmasa
parents: 2885
diff changeset
  8499
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8500
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
  8501
  HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8502
  if (_span.contains(addr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8503
      !_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8504
    if (_bit_map->par_mark(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8505
      bool simulate_overflow = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8506
      NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8507
        if (CMSMarkStackOverflowALot &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8508
            _collector->par_simulate_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8509
          // simulate a stack overflow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8510
          simulate_overflow = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8511
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8512
      )
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8513
      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
  8514
        _collector->par_push_on_overflow_list(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8515
        _collector->_par_kac_ovflw++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8516
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8517
    } // Else another thread got there already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8518
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8519
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8520
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8521
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
  8522
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
  8523
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8524
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8525
//  CMSExpansionCause                /////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8526
//////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8527
const char* CMSExpansionCause::to_string(CMSExpansionCause::Cause cause) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8528
  switch (cause) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8529
    case _no_expansion:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8530
      return "No expansion";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8531
    case _satisfy_free_ratio:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8532
      return "Free ratio";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8533
    case _satisfy_promotion:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8534
      return "Satisfy promotion";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8535
    case _satisfy_allocation:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8536
      return "allocation";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8537
    case _allocate_par_lab:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8538
      return "Par LAB";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8539
    case _allocate_par_spooling_space:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8540
      return "Par Spooling Space";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8541
    case _adaptive_size_policy:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8542
      return "Ergonomics";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8543
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8544
      return "unknown";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8545
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8546
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8547
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8548
void CMSDrainMarkingStackClosure::do_void() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8549
  // the max number to take from overflow list at a time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8550
  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
  8551
  assert(!_concurrent_precleaning || _collector->overflow_list_is_empty(),
6b43d186eb8d 6722113: CMS: Incorrect overflow handling during precleaning of Reference lists
ysr
parents: 1392
diff changeset
  8552
         "Overflow list should be NULL during concurrent phases");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8553
  while (!_mark_stack->isEmpty() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8554
         // if stack is empty, check the overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8555
         _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
  8556
    oop obj = _mark_stack->pop();
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 341
diff changeset
  8557
    HeapWord* addr = (HeapWord*)obj;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8558
    assert(_span.contains(addr), "Should be within span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8559
    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
  8560
    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
  8561
    obj->oop_iterate(_keep_alive);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8562
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8563
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8564
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8565
void CMSParDrainMarkingStackClosure::do_void() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8566
  // drain queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8567
  trim_queue(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8568
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8569
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8570
// Trim our work_queue so its length is below max at return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8571
void CMSParDrainMarkingStackClosure::trim_queue(uint max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8572
  while (_work_queue->size() > max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8573
    oop new_oop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8574
    if (_work_queue->pop_local(new_oop)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8575
      assert(new_oop->is_oop(), "Expected an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8576
      assert(_bit_map->isMarked((HeapWord*)new_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8577
             "no white objects on this stack!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8578
      assert(_span.contains((HeapWord*)new_oop), "Out of bounds oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8579
      // iterate over the oops in this oop, marking and pushing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8580
      // the ones in CMS heap (i.e. in _span).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8581
      new_oop->oop_iterate(&_mark_and_push);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8582
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8583
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8584
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8585
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8586
////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8587
// Support for Marking Stack Overflow list handling and related code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8588
////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8589
// Much of the following code is similar in shape and spirit to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8590
// code used in ParNewGC. We should try and share that code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8591
// as much as possible in the future.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8592
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8593
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8594
// Debugging support for CMSStackOverflowALot
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8595
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8596
// It's OK to call this multi-threaded;  the worst thing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8597
// that can happen is that we'll get a bunch of closely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8598
// spaced simulated oveflows, but that's OK, in fact
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8599
// probably good as it would exercise the overflow code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8600
// under contention.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8601
bool CMSCollector::simulate_overflow() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8602
  if (_overflow_counter-- <= 0) { // just being defensive
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8603
    _overflow_counter = CMSMarkStackOverflowInterval;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8604
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8605
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8606
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8607
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8608
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8609
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8610
bool CMSCollector::par_simulate_overflow() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8611
  return simulate_overflow();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8612
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8613
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8614
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8615
// Single-threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8616
bool CMSCollector::take_from_overflow_list(size_t num, CMSMarkStack* stack) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8617
  assert(stack->isEmpty(), "Expected precondition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8618
  assert(stack->capacity() > num, "Shouldn't bite more than can chew");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8619
  size_t i = num;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8620
  oop  cur = _overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8621
  const markOop proto = markOopDesc::prototype();
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8622
  NOT_PRODUCT(ssize_t n = 0;)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8623
  for (oop next; i > 0 && cur != NULL; cur = next, i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8624
    next = oop(cur->mark());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8625
    cur->set_mark(proto);   // until proven otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8626
    assert(cur->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8627
    bool res = stack->push(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8628
    assert(res, "Bit off more than can chew?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8629
    NOT_PRODUCT(n++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8630
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8631
  _overflow_list = cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8632
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8633
  assert(_num_par_pushes >= n, "Too many pops?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8634
  _num_par_pushes -=n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8635
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8636
  return !stack->isEmpty();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8637
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8638
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8639
#define BUSY  (oop(0x1aff1aff))
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8640
// (MT-safe) Get a prefix of at most "num" from the list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8641
// The overflow list is chained through the mark word of
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8642
// each object in the list. We fetch the entire list,
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8643
// break off a prefix of the right size and return the
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8644
// remainder. If other threads try to take objects from
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8645
// the overflow list at that time, they will wait for
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8646
// some time to see if data becomes available. If (and
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8647
// only if) another thread places one or more object(s)
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8648
// on the global list before we have returned the suffix
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8649
// to the global list, we will walk down our local list
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8650
// to find its end and append the global list to
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8651
// our suffix before returning it. This suffix walk can
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8652
// prove to be expensive (quadratic in the amount of traffic)
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8653
// when there are many objects in the overflow list and
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8654
// there is much producer-consumer contention on the list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8655
// *NOTE*: The overflow list manipulation code here and
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8656
// in ParNewGeneration:: are very similar in shape,
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8657
// except that in the ParNew case we use the old (from/eden)
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8658
// copy of the object to thread the list via its klass word.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8659
// Because of the common code, if you make any changes in
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8660
// the code below, please check the ParNew version to see if
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8661
// similar changes might be needed.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8662
// CR 6797058 has been filed to consolidate the common code.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8663
bool CMSCollector::par_take_from_overflow_list(size_t num,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8664
                                               OopTaskQueue* work_q) {
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8665
  assert(work_q->size() == 0, "First empty local work queue");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8666
  assert(num < work_q->max_elems(), "Can't bite more than we can chew");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8667
  if (_overflow_list == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8668
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8669
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8670
  // Grab the entire list; we'll put back a suffix
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8671
  oop prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8672
  Thread* tid = Thread::current();
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8673
  size_t CMSOverflowSpinCount = (size_t)ParallelGCThreads;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8674
  size_t sleep_time_millis = MAX2((size_t)1, num/100);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8675
  // If the list is busy, we spin for a short while,
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8676
  // sleeping between attempts to get the list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8677
  for (size_t spin = 0; prefix == BUSY && spin < CMSOverflowSpinCount; spin++) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8678
    os::sleep(tid, sleep_time_millis, false);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8679
    if (_overflow_list == NULL) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8680
      // Nothing left to take
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8681
      return false;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8682
    } else if (_overflow_list != BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8683
      // Try and grab the prefix
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8684
      prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8685
    }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8686
  }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8687
  // If the list was found to be empty, or we spun long
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8688
  // enough, we give up and return empty-handed. If we leave
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8689
  // the list in the BUSY state below, it must be the case that
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8690
  // some other thread holds the overflow list and will set it
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8691
  // to a non-BUSY state in the future.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8692
  if (prefix == NULL || prefix == BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8693
     // Nothing to take or waited long enough
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8694
     if (prefix == NULL) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8695
       // Write back the NULL in case we overwrote it with BUSY above
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8696
       // and it is still the same value.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8697
       (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8698
     }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8699
     return false;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8700
  }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8701
  assert(prefix != NULL && prefix != BUSY, "Error");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8702
  size_t i = num;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8703
  oop cur = prefix;
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8704
  // Walk down the first "num" objects, unless we reach the end.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8705
  for (; i > 1 && cur->mark() != NULL; cur = oop(cur->mark()), i--);
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8706
  if (cur->mark() == NULL) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8707
    // We have "num" or fewer elements in the list, so there
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8708
    // is nothing to return to the global list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8709
    // Write back the NULL in lieu of the BUSY we wrote
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8710
    // above, if it is still the same value.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8711
    if (_overflow_list == BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8712
      (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8713
    }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8714
  } else {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8715
    // Chop off the suffix and rerturn it to the global list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8716
    assert(cur->mark() != BUSY, "Error");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8717
    oop suffix_head = cur->mark(); // suffix will be put back on global list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8718
    cur->set_mark(NULL);           // break off suffix
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8719
    // It's possible that the list is still in the empty(busy) state
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8720
    // we left it in a short while ago; in that case we may be
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8721
    // able to place back the suffix without incurring the cost
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8722
    // of a walk down the list.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8723
    oop observed_overflow_list = _overflow_list;
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8724
    oop cur_overflow_list = observed_overflow_list;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8725
    bool attached = false;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8726
    while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8727
      observed_overflow_list =
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8728
        (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8729
      if (cur_overflow_list == observed_overflow_list) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8730
        attached = true;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8731
        break;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8732
      } else cur_overflow_list = observed_overflow_list;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8733
    }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8734
    if (!attached) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8735
      // Too bad, someone else sneaked in (at least) an element; we'll need
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8736
      // to do a splice. Find tail of suffix so we can prepend suffix to global
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8737
      // list.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8738
      for (cur = suffix_head; cur->mark() != NULL; cur = (oop)(cur->mark()));
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8739
      oop suffix_tail = cur;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8740
      assert(suffix_tail != NULL && suffix_tail->mark() == NULL,
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8741
             "Tautology");
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8742
      observed_overflow_list = _overflow_list;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8743
      do {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8744
        cur_overflow_list = observed_overflow_list;
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8745
        if (cur_overflow_list != BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8746
          // Do the splice ...
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8747
          suffix_tail->set_mark(markOop(cur_overflow_list));
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8748
        } else { // cur_overflow_list == BUSY
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8749
          suffix_tail->set_mark(NULL);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8750
        }
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8751
        // ... and try to place spliced list back on overflow_list ...
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8752
        observed_overflow_list =
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8753
          (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8754
      } while (cur_overflow_list != observed_overflow_list);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8755
      // ... until we have succeeded in doing so.
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8756
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8757
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8758
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8759
  // Push the prefix elements on work_q
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8760
  assert(prefix != NULL, "control point invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8761
  const markOop proto = markOopDesc::prototype();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8762
  oop next;
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8763
  NOT_PRODUCT(ssize_t n = 0;)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8764
  for (cur = prefix; cur != NULL; cur = next) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8765
    next = oop(cur->mark());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8766
    cur->set_mark(proto);   // until proven otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8767
    assert(cur->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8768
    bool res = work_q->push(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8769
    assert(res, "Bit off more than we can chew?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8770
    NOT_PRODUCT(n++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8771
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8772
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8773
  assert(_num_par_pushes >= n, "Too many pops?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8774
  Atomic::add_ptr(-(intptr_t)n, &_num_par_pushes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8775
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8776
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8777
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8778
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8779
// Single-threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8780
void CMSCollector::push_on_overflow_list(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8781
  NOT_PRODUCT(_num_par_pushes++;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8782
  assert(p->is_oop(), "Not an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8783
  preserve_mark_if_necessary(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8784
  p->set_mark((markOop)_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8785
  _overflow_list = p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8786
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8787
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8788
// Multi-threaded; use CAS to prepend to overflow list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8789
void CMSCollector::par_push_on_overflow_list(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8790
  NOT_PRODUCT(Atomic::inc_ptr(&_num_par_pushes);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8791
  assert(p->is_oop(), "Not an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8792
  par_preserve_mark_if_necessary(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8793
  oop observed_overflow_list = _overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8794
  oop cur_overflow_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8795
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8796
    cur_overflow_list = observed_overflow_list;
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8797
    if (cur_overflow_list != BUSY) {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8798
      p->set_mark(markOop(cur_overflow_list));
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8799
    } else {
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8800
      p->set_mark(NULL);
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8801
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8802
    observed_overflow_list =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8803
      (oop) Atomic::cmpxchg_ptr(p, &_overflow_list, cur_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8804
  } while (cur_overflow_list != observed_overflow_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8805
}
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8806
#undef BUSY
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8807
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8808
// Single threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8809
// General Note on GrowableArray: pushes may silently fail
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8810
// because we are (temporarily) out of C-heap for expanding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8811
// the stack. The problem is quite ubiquitous and affects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8812
// a lot of code in the JVM. The prudent thing for GrowableArray
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8813
// to do (for now) is to exit with an error. However, that may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8814
// be too draconian in some cases because the caller may be
1910
386106352d02 6786503: Overflow list performance can be improved
ysr
parents: 1894
diff changeset
  8815
// able to recover without much harm. For such cases, we
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8816
// should probably introduce a "soft_push" method which returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8817
// an indication of success or failure with the assumption that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8818
// the caller may be able to recover from a failure; code in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8819
// the VM can then be changed, incrementally, to deal with such
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8820
// failures where possible, thus, incrementally hardening the VM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8821
// in such low resource situations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8822
void CMSCollector::preserve_mark_work(oop p, markOop m) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8823
  if (_preserved_oop_stack == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8824
    assert(_preserved_mark_stack == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8825
           "bijection with preserved_oop_stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8826
    // Allocate the stacks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8827
    _preserved_oop_stack  = new (ResourceObj::C_HEAP)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8828
      GrowableArray<oop>(PreserveMarkStackSize, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8829
    _preserved_mark_stack = new (ResourceObj::C_HEAP)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8830
      GrowableArray<markOop>(PreserveMarkStackSize, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8831
    if (_preserved_oop_stack == NULL || _preserved_mark_stack == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8832
      vm_exit_out_of_memory(2* PreserveMarkStackSize * sizeof(oop) /* punt */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8833
                            "Preserved Mark/Oop Stack for CMS (C-heap)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8834
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8835
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8836
  _preserved_oop_stack->push(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8837
  _preserved_mark_stack->push(m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8838
  assert(m == p->mark(), "Mark word changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8839
  assert(_preserved_oop_stack->length() == _preserved_mark_stack->length(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8840
         "bijection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8841
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8842
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8843
// Single threaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8844
void CMSCollector::preserve_mark_if_necessary(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8845
  markOop m = p->mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8846
  if (m->must_be_preserved(p)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8847
    preserve_mark_work(p, m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8848
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8849
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8850
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8851
void CMSCollector::par_preserve_mark_if_necessary(oop p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8852
  markOop m = p->mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8853
  if (m->must_be_preserved(p)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8854
    MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8855
    // Even though we read the mark word without holding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8856
    // the lock, we are assured that it will not change
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8857
    // because we "own" this oop, so no other thread can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8858
    // be trying to push it on the overflow list; see
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8859
    // the assertion in preserve_mark_work() that checks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8860
    // that m == p->mark().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8861
    preserve_mark_work(p, m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8862
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8863
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8864
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8865
// We should be able to do this multi-threaded,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8866
// a chunk of stack being a task (this is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8867
// correct because each oop only ever appears
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8868
// once in the overflow list. However, it's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8869
// not very easy to completely overlap this with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8870
// other operations, so will generally not be done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8871
// until all work's been completed. Because we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8872
// expect the preserved oop stack (set) to be small,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8873
// it's probably fine to do this single-threaded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8874
// We can explore cleverer concurrent/overlapped/parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8875
// processing of preserved marks if we feel the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8876
// need for this in the future. Stack overflow should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8877
// be so rare in practice and, when it happens, its
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8878
// effect on performance so great that this will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8879
// likely just be in the noise anyway.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8880
void CMSCollector::restore_preserved_marks_if_any() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8881
  if (_preserved_oop_stack == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8882
    assert(_preserved_mark_stack == NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8883
           "bijection with preserved_oop_stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8884
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8885
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8886
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8887
  assert(SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8888
         "world should be stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8889
  assert(Thread::current()->is_ConcurrentGC_thread() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8890
         Thread::current()->is_VM_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8891
         "should be single-threaded");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8892
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8893
  int length = _preserved_oop_stack->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8894
  assert(_preserved_mark_stack->length() == length, "bijection");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8895
  for (int i = 0; i < length; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8896
    oop p = _preserved_oop_stack->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8897
    assert(p->is_oop(), "Should be an oop");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8898
    assert(_span.contains(p), "oop should be in _span");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8899
    assert(p->mark() == markOopDesc::prototype(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8900
           "Set when taken from overflow list");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8901
    markOop m = _preserved_mark_stack->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8902
    p->set_mark(m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8903
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8904
  _preserved_mark_stack->clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8905
  _preserved_oop_stack->clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8906
  assert(_preserved_mark_stack->is_empty() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8907
         _preserved_oop_stack->is_empty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8908
         "stacks were cleared above");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8909
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8910
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8911
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8912
bool CMSCollector::no_preserved_marks() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8913
  return (   (   _preserved_mark_stack == NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8914
              && _preserved_oop_stack == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8915
          || (   _preserved_mark_stack->is_empty()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8916
              && _preserved_oop_stack->is_empty()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8917
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8918
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8919
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8920
CMSAdaptiveSizePolicy* ASConcurrentMarkSweepGeneration::cms_size_policy() const
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8921
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8922
  GenCollectedHeap* gch = (GenCollectedHeap*) GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8923
  CMSAdaptiveSizePolicy* size_policy =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8924
    (CMSAdaptiveSizePolicy*) gch->gen_policy()->size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8925
  assert(size_policy->is_gc_cms_adaptive_size_policy(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8926
    "Wrong type for size policy");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8927
  return size_policy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8928
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8929
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8930
void ASConcurrentMarkSweepGeneration::resize(size_t cur_promo_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8931
                                           size_t desired_promo_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8932
  if (cur_promo_size < desired_promo_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8933
    size_t expand_bytes = desired_promo_size - cur_promo_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8934
    if (PrintAdaptiveSizePolicy && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8935
      gclog_or_tty->print_cr(" ASConcurrentMarkSweepGeneration::resize "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8936
        "Expanding tenured generation by " SIZE_FORMAT " (bytes)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8937
        expand_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8938
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8939
    expand(expand_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8940
           MinHeapDeltaBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8941
           CMSExpansionCause::_adaptive_size_policy);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8942
  } else if (desired_promo_size < cur_promo_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8943
    size_t shrink_bytes = cur_promo_size - desired_promo_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8944
    if (PrintAdaptiveSizePolicy && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8945
      gclog_or_tty->print_cr(" ASConcurrentMarkSweepGeneration::resize "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8946
        "Shrinking tenured generation by " SIZE_FORMAT " (bytes)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8947
        shrink_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8948
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8949
    shrink(shrink_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8950
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8951
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8952
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8953
CMSGCAdaptivePolicyCounters* ASConcurrentMarkSweepGeneration::gc_adaptive_policy_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8954
  GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8955
  CMSGCAdaptivePolicyCounters* counters =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8956
    (CMSGCAdaptivePolicyCounters*) gch->collector_policy()->counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8957
  assert(counters->kind() == GCPolicyCounters::CMSGCAdaptivePolicyCountersKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8958
    "Wrong kind of counters");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8959
  return counters;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8960
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8961
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8962
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8963
void ASConcurrentMarkSweepGeneration::update_counters() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8964
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8965
    _space_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8966
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8967
    CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8968
    GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8969
    CMSGCStats* gc_stats_l = (CMSGCStats*) gc_stats();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8970
    assert(gc_stats_l->kind() == GCStats::CMSGCStatsKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8971
      "Wrong gc statistics type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8972
    counters->update_counters(gc_stats_l);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8973
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8974
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8975
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8976
void ASConcurrentMarkSweepGeneration::update_counters(size_t used) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8977
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8978
    _space_counters->update_used(used);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8979
    _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8980
    _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8981
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8982
    CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8983
    GenCollectedHeap* gch = GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8984
    CMSGCStats* gc_stats_l = (CMSGCStats*) gc_stats();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8985
    assert(gc_stats_l->kind() == GCStats::CMSGCStatsKind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8986
      "Wrong gc statistics type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8987
    counters->update_counters(gc_stats_l);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8988
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8989
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8990
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8991
// The desired expansion delta is computed so that:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8992
// . desired free percentage or greater is used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8993
void ASConcurrentMarkSweepGeneration::compute_new_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8994
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8995
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8996
  GenCollectedHeap* gch = (GenCollectedHeap*) GenCollectedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8997
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8998
  // If incremental collection failed, we just want to expand
489c9b5090e2 Initial load
duke
parents:
diff changeset
  8999
  // to the limit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9000
  if (incremental_collection_failed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9001
    clear_incremental_collection_failed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9002
    grow_to_reserved();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9003
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9004
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9005
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9006
  assert(UseAdaptiveSizePolicy, "Should be using adaptive sizing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9007
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9008
  assert(gch->kind() == CollectedHeap::GenCollectedHeap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9009
    "Wrong type of heap");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9010
  int prev_level = level() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9011
  assert(prev_level >= 0, "The cms generation is the lowest generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9012
  Generation* prev_gen = gch->get_gen(prev_level);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9013
  assert(prev_gen->kind() == Generation::ASParNew,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9014
    "Wrong type of young generation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9015
  ParNewGeneration* younger_gen = (ParNewGeneration*) prev_gen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9016
  size_t cur_eden = younger_gen->eden()->capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9017
  CMSAdaptiveSizePolicy* size_policy = cms_size_policy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9018
  size_t cur_promo = free();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9019
  size_policy->compute_tenured_generation_free_space(cur_promo,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9020
                                                       max_available(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9021
                                                       cur_eden);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9022
  resize(cur_promo, size_policy->promo_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9023
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9024
  // Record the new size of the space in the cms generation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9025
  // that is available for promotions.  This is temporary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9026
  // It should be the desired promo size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9027
  size_policy->avg_cms_promo()->sample(free());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9028
  size_policy->avg_old_live()->sample(used());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9029
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9030
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9031
    CMSGCAdaptivePolicyCounters* counters = gc_adaptive_policy_counters();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9032
    counters->update_cms_capacity_counter(capacity());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9033
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9034
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9035
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9036
void ASConcurrentMarkSweepGeneration::shrink_by(size_t desired_bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9037
  assert_locked_or_safepoint(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9038
  assert_lock_strong(freelistLock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9039
  HeapWord* old_end = _cmsSpace->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9040
  HeapWord* unallocated_start = _cmsSpace->unallocated_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9041
  assert(old_end >= unallocated_start, "Miscalculation of unallocated_start");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9042
  FreeChunk* chunk_at_end = find_chunk_at_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9043
  if (chunk_at_end == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9044
    // No room to shrink
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9045
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9046
      gclog_or_tty->print_cr("No room to shrink: old_end  "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9047
        PTR_FORMAT "  unallocated_start  " PTR_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9048
        " chunk_at_end  " PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9049
        old_end, unallocated_start, chunk_at_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9050
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9051
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9052
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9054
    // Find the chunk at the end of the space and determine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9055
    // how much it can be shrunk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9056
    size_t shrinkable_size_in_bytes = chunk_at_end->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9057
    size_t aligned_shrinkable_size_in_bytes =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9058
      align_size_down(shrinkable_size_in_bytes, os::vm_page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9059
    assert(unallocated_start <= chunk_at_end->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9060
      "Inconsistent chunk at end of space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9061
    size_t bytes = MIN2(desired_bytes, aligned_shrinkable_size_in_bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9062
    size_t word_size_before = heap_word_size(_virtual_space.committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9063
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9064
    // Shrink the underlying space
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9065
    _virtual_space.shrink_by(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9066
    if (PrintGCDetails && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9067
      gclog_or_tty->print_cr("ConcurrentMarkSweepGeneration::shrink_by:"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9068
        " desired_bytes " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9069
        " shrinkable_size_in_bytes " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9070
        " aligned_shrinkable_size_in_bytes " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9071
        "  bytes  " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9072
        desired_bytes, shrinkable_size_in_bytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9073
        aligned_shrinkable_size_in_bytes, bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9074
      gclog_or_tty->print_cr("          old_end  " SIZE_FORMAT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9075
        "  unallocated_start  " SIZE_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9076
        old_end, unallocated_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9077
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9078
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9079
    // If the space did shrink (shrinking is not guaranteed),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9080
    // shrink the chunk at the end by the appropriate amount.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9081
    if (((HeapWord*)_virtual_space.high()) < old_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9082
      size_t new_word_size =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9083
        heap_word_size(_virtual_space.committed_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9084
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9085
      // Have to remove the chunk from the dictionary because it is changing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9086
      // size and might be someplace elsewhere in the dictionary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9087
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9088
      // Get the chunk at end, shrink it, and put it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9089
      // back.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9090
      _cmsSpace->removeChunkFromDictionary(chunk_at_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9091
      size_t word_size_change = word_size_before - new_word_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9092
      size_t chunk_at_end_old_size = chunk_at_end->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9093
      assert(chunk_at_end_old_size >= word_size_change,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9094
        "Shrink is too large");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9095
      chunk_at_end->setSize(chunk_at_end_old_size -
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9096
                          word_size_change);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9097
      _cmsSpace->freed((HeapWord*) chunk_at_end->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9098
        word_size_change);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9099
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9100
      _cmsSpace->returnChunkToDictionary(chunk_at_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9101
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9102
      MemRegion mr(_cmsSpace->bottom(), new_word_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9103
      _bts->resize(new_word_size);  // resize the block offset shared array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9104
      Universe::heap()->barrier_set()->resize_covered_region(mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9105
      _cmsSpace->assert_locked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9106
      _cmsSpace->set_end((HeapWord*)_virtual_space.high());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9107
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9108
      NOT_PRODUCT(_cmsSpace->dictionary()->verify());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9109
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9110
      // update the space and generation capacity counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9111
      if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9112
        _space_counters->update_capacity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9113
        _gen_counters->update_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9114
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9115
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9116
      if (Verbose && PrintGCDetails) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9117
        size_t new_mem_size = _virtual_space.committed_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9118
        size_t old_mem_size = new_mem_size + bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9119
        gclog_or_tty->print_cr("Shrinking %s from %ldK by %ldK to %ldK",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9120
                      name(), old_mem_size/K, bytes/K, new_mem_size/K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9121
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9122
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9123
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9124
    assert(_cmsSpace->unallocated_block() <= _cmsSpace->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9125
      "Inconsistency at end of space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9126
    assert(chunk_at_end->end() == _cmsSpace->end(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9127
      "Shrinking is inconsistent");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9128
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9129
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9130
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9131
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9132
// Transfer some number of overflown objects to usual marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9133
// stack. Return true if some objects were transferred.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9134
bool MarkRefsIntoAndScanClosure::take_from_overflow_list() {
2346
3aa355016e90 6819891: ParNew: Fix work queue overflow code to deal correctly with +UseCompressedOops
ysr
parents: 2154
diff changeset
  9135
  size_t num = MIN2((size_t)(_mark_stack->capacity() - _mark_stack->length())/4,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9136
                    (size_t)ParGCDesiredObjsFromOverflowList);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9137
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9138
  bool res = _collector->take_from_overflow_list(num, _mark_stack);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9139
  assert(_collector->overflow_list_is_empty() || res,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9140
         "If list is not empty, we should have taken something");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9141
  assert(!res || !_mark_stack->isEmpty(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9142
         "If we took something, it should now be on our stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9143
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9144
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9145
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9146
size_t MarkDeadObjectsClosure::do_blk(HeapWord* addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9147
  size_t res = _sp->block_size_no_stall(addr, _collector);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9148
  assert(res != 0, "Should always be able to compute a size");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9149
  if (_sp->block_is_obj(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9150
    if (_live_bit_map->isMarked(addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9151
      // It can't have been dead in a previous cycle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9152
      guarantee(!_dead_bit_map->isMarked(addr), "No resurrection!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9153
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9154
      _dead_bit_map->mark(addr);      // mark the dead object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9155
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9156
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9157
  return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  9158
}