hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 1 489c9b5090e2
child 185 cda2a1eb4be5
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2001-2006 Sun Microsystems, Inc.  All Rights Reserved.
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
// Classes in support of keeping track of promotions into a non-Contiguous
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
// space, in this case a CompactibleFreeListSpace.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
#define CFLS_LAB_REFILL_STATS 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
// Forward declarations
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
class CompactibleFreeListSpace;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
class BlkClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
class BlkClosureCareful;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
class UpwardsObjectClosure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
class ObjectClosureCareful;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
class Klass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
class PromotedObject VALUE_OBJ_CLASS_SPEC {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
  enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
    promoted_mask  = right_n_bits(2),   // i.e. 0x3
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
    displaced_mark = nth_bit(2),        // i.e. 0x4
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
    next_mask      = ~(right_n_bits(3)) // i.e. ~(0x7)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
  intptr_t _next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
  inline PromotedObject* next() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
    return (PromotedObject*)(_next & next_mask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  inline void setNext(PromotedObject* x) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
    assert(((intptr_t)x & ~next_mask) == 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
           "Conflict in bit usage, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
           " or insufficient alignment of objects");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
    _next |= (intptr_t)x;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  inline void setPromotedMark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
    _next |= promoted_mask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  inline bool hasPromotedMark() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
    return (_next & promoted_mask) == promoted_mask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  inline void setDisplacedMark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
    _next |= displaced_mark;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  inline bool hasDisplacedMark() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
    return (_next & displaced_mark) != 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
  inline void clearNext()        { _next = 0; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  debug_only(void *next_addr() { return (void *) &_next; })
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
class SpoolBlock: public FreeChunk {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  friend class PromotionInfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
 protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  SpoolBlock*  nextSpoolBlock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  size_t       bufferSize;        // number of usable words in this block
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  markOop*     displacedHdr;      // the displaced headers start here
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  // Note about bufferSize: it denotes the number of entries available plus 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  // legal indices range from 1 through BufferSize - 1.  See the verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  // code verify() that counts the number of displaced headers spooled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  size_t computeBufferSize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
    return (size() * sizeof(HeapWord) - sizeof(*this)) / sizeof(markOop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  void init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
    bufferSize = computeBufferSize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
    displacedHdr = (markOop*)&displacedHdr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
    nextSpoolBlock = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
class PromotionInfo VALUE_OBJ_CLASS_SPEC {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  bool            _tracking;      // set if tracking
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  CompactibleFreeListSpace* _space; // the space to which this belongs
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  PromotedObject* _promoHead;     // head of list of promoted objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  PromotedObject* _promoTail;     // tail of list of promoted objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  SpoolBlock*     _spoolHead;     // first spooling block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  SpoolBlock*     _spoolTail;     // last  non-full spooling block or null
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
  SpoolBlock*     _splice_point;  // when _spoolTail is null, holds list tail
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  SpoolBlock*     _spareSpool;    // free spool buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  size_t          _firstIndex;    // first active index in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
                                  // first spooling block (_spoolHead)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  size_t          _nextIndex;     // last active index + 1 in last
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
                                  // spooling block (_spoolTail)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  // ensure that spooling space exists; return true if there is spooling space
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  bool ensure_spooling_space_work();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  PromotionInfo() :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
    _tracking(0), _space(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
    _promoHead(NULL), _promoTail(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
    _spoolHead(NULL), _spoolTail(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
    _spareSpool(NULL), _firstIndex(1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
    _nextIndex(1) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  bool noPromotions() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
    assert(_promoHead != NULL || _promoTail == NULL, "list inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
    return _promoHead == NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  void startTrackingPromotions();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  void stopTrackingPromotions();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  bool tracking() const          { return _tracking;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  void track(PromotedObject* trackOop);      // keep track of a promoted oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  // The following variant must be used when trackOop is not fully
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  // initialized and has a NULL klass:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  void track(PromotedObject* trackOop, klassOop klassOfOop); // keep track of a promoted oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  void setSpace(CompactibleFreeListSpace* sp) { _space = sp; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  CompactibleFreeListSpace* space() const     { return _space; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  markOop nextDisplacedHeader(); // get next header & forward spool pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  void    saveDisplacedHeader(markOop hdr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
                                 // save header and forward spool
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  inline size_t refillSize() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  SpoolBlock* getSpoolBlock();   // return a free spooling block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  inline bool has_spooling_space() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
    return _spoolTail != NULL && _spoolTail->bufferSize > _nextIndex;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  // ensure that spooling space exists
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  bool ensure_spooling_space() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
    return has_spooling_space() || ensure_spooling_space_work();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  #define PROMOTED_OOPS_ITERATE_DECL(OopClosureType, nv_suffix)  \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
    void promoted_oops_iterate##nv_suffix(OopClosureType* cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  ALL_SINCE_SAVE_MARKS_CLOSURES(PROMOTED_OOPS_ITERATE_DECL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  #undef PROMOTED_OOPS_ITERATE_DECL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  void promoted_oops_iterate(OopsInGenClosure* cl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    promoted_oops_iterate_v(cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  void verify()  const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  void reset() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
    _promoHead = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    _promoTail = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
    _spoolHead = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    _spoolTail = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
    _spareSpool = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
    _firstIndex = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
    _nextIndex = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
class LinearAllocBlock VALUE_OBJ_CLASS_SPEC {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  LinearAllocBlock() : _ptr(0), _word_size(0), _refillSize(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
    _allocation_size_limit(0) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  void set(HeapWord* ptr, size_t word_size, size_t refill_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
    size_t allocation_size_limit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    _ptr = ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    _word_size = word_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
    _refillSize = refill_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    _allocation_size_limit = allocation_size_limit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  HeapWord* _ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  size_t    _word_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  size_t    _refillSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  size_t    _allocation_size_limit;  // largest size that will be allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
// Concrete subclass of CompactibleSpace that implements
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
// a free list space, such as used in the concurrent mark sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
// generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
class CompactibleFreeListSpace: public CompactibleSpace {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  friend class VMStructs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  friend class ConcurrentMarkSweepGeneration;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
  friend class ASConcurrentMarkSweepGeneration;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  friend class CMSCollector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  friend class CMSPermGenGen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  // Local alloc buffer for promotion into this space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  friend class CFLS_LAB;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  // "Size" of chunks of work (executed during parallel remark phases
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  // of CMS collection); this probably belongs in CMSCollector, although
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  // it's cached here because it's used in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  // initialize_sequential_subtasks_for_rescan() which modifies
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  // par_seq_tasks which also lives in Space. XXX
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  const size_t _rescan_task_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  const size_t _marking_task_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  // Yet another sequential tasks done structure. This supports
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  // CMS GC, where we have threads dynamically
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
  // claiming sub-tasks from a larger parallel task.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  SequentialSubTasksDone _conc_par_seq_tasks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  BlockOffsetArrayNonContigSpace _bt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  CMSCollector* _collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  ConcurrentMarkSweepGeneration* _gen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  // Data structures for free blocks (used during allocation/sweeping)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  // Allocation is done linearly from two different blocks depending on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
  // whether the request is small or large, in an effort to reduce
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  // fragmentation. We assume that any locking for allocation is done
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  // by the containing generation. Thus, none of the methods in this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  // space are re-entrant.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  enum SomeConstants {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
    SmallForLinearAlloc = 16,        // size < this then use _sLAB
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
    SmallForDictionary  = 257,       // size < this then use _indexedFreeList
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
    IndexSetSize        = SmallForDictionary,  // keep this odd-sized
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
    IndexSetStart       = MinObjAlignment,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
    IndexSetStride      = MinObjAlignment
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
  enum FitStrategyOptions {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
    FreeBlockStrategyNone = 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
    FreeBlockBestFitFirst
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  PromotionInfo _promoInfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  // helps to impose a global total order on freelistLock ranks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  // assumes that CFLSpace's are allocated in global total order
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  static int   _lockRank;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  // a lock protecting the free lists and free blocks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  // mutable because of ubiquity of locking even for otherwise const methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  mutable Mutex _freelistLock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  // locking verifier convenience function
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  void assert_locked() const PRODUCT_RETURN;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
  // Linear allocation blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  LinearAllocBlock _smallLinearAllocBlock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  FreeBlockDictionary::DictionaryChoice _dictionaryChoice;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  FreeBlockDictionary* _dictionary;    // ptr to dictionary for large size blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  FreeList _indexedFreeList[IndexSetSize];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
                                       // indexed array for small size blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  // allocation stategy
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  bool       _fitStrategy;      // Use best fit strategy.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  bool       _adaptive_freelists; // Use adaptive freelists
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  // This is an address close to the largest free chunk in the heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  // It is currently assumed to be at the end of the heap.  Free
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  // chunks with addresses greater than nearLargestChunk are coalesced
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  // in an effort to maintain a large chunk at the end of the heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  HeapWord*  _nearLargestChunk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  // Used to keep track of limit of sweep for the space
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  HeapWord* _sweep_limit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  // Support for compacting cms
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  HeapWord* cross_threshold(HeapWord* start, HeapWord* end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
  HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
  // Initialization helpers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
  void initializeIndexedFreeListArray();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  // Extra stuff to manage promotion parallelism.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  // a lock protecting the dictionary during par promotion allocation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  mutable Mutex _parDictionaryAllocLock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  Mutex* parDictionaryAllocLock() const { return &_parDictionaryAllocLock; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  // Locks protecting the exact lists during par promotion allocation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  Mutex* _indexedFreeListParLocks[IndexSetSize];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
#if CFLS_LAB_REFILL_STATS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  // Some statistics.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  jint  _par_get_chunk_from_small;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  jint  _par_get_chunk_from_large;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  // Attempt to obtain up to "n" blocks of the size "word_sz" (which is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  // required to be smaller than "IndexSetSize".)  If successful,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  // adds them to "fl", which is required to be an empty free list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  // If the count of "fl" is negative, it's absolute value indicates a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  // number of free chunks that had been previously "borrowed" from global
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  // list of size "word_sz", and must now be decremented.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  void par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
  // Allocation helper functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
  // Allocate using a strategy that takes from the indexed free lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
  // first.  This allocation strategy assumes a companion sweeping
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
  // strategy that attempts to keep the needed number of chunks in each
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
  // indexed free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
  HeapWord* allocate_adaptive_freelists(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
  // Allocate from the linear allocation buffers first.  This allocation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  // strategy assumes maximal coalescing can maintain chunks large enough
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
  // to be used as linear allocation buffers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  HeapWord* allocate_non_adaptive_freelists(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  // Gets a chunk from the linear allocation block (LinAB).  If there
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  // is not enough space in the LinAB, refills it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  HeapWord*  getChunkFromLinearAllocBlock(LinearAllocBlock* blk, size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
  HeapWord*  getChunkFromSmallLinearAllocBlock(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
  // Get a chunk from the space remaining in the linear allocation block.  Do
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
  // not attempt to refill if the space is not available, return NULL.  Do the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
  // repairs on the linear allocation block as appropriate.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  HeapWord*  getChunkFromLinearAllocBlockRemainder(LinearAllocBlock* blk, size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  inline HeapWord*  getChunkFromSmallLinearAllocBlockRemainder(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  // Helper function for getChunkFromIndexedFreeList.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
  // Replenish the indexed free list for this "size".  Do not take from an
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
  // underpopulated size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
  FreeChunk*  getChunkFromIndexedFreeListHelper(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
  // Get a chunk from the indexed free list.  If the indexed free list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  // does not have a free chunk, try to replenish the indexed free list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  // then get the free chunk from the replenished indexed free list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  inline FreeChunk* getChunkFromIndexedFreeList(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  // The returned chunk may be larger than requested (or null).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  FreeChunk* getChunkFromDictionary(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  // The returned chunk is the exact size requested (or null).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  FreeChunk* getChunkFromDictionaryExact(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  // Find a chunk in the indexed free list that is the best
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  // fit for size "numWords".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  FreeChunk* bestFitSmall(size_t numWords);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
  // For free list "fl" of chunks of size > numWords,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  // remove a chunk, split off a chunk of size numWords
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  // and return it.  The split off remainder is returned to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  // the free lists.  The old name for getFromListGreater
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  // was lookInListGreater.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
  FreeChunk* getFromListGreater(FreeList* fl, size_t numWords);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  // Get a chunk in the indexed free list or dictionary,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  // by considering a larger chunk and splitting it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  FreeChunk* getChunkFromGreater(size_t numWords);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  //  Verify that the given chunk is in the indexed free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
  bool verifyChunkInIndexedFreeLists(FreeChunk* fc) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  // Remove the specified chunk from the indexed free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  void       removeChunkFromIndexedFreeList(FreeChunk* fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
  // Remove the specified chunk from the dictionary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  void       removeChunkFromDictionary(FreeChunk* fc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  // Split a free chunk into a smaller free chunk of size "new_size".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  // Return the smaller free chunk and return the remainder to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  // free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  FreeChunk* splitChunkAndReturnRemainder(FreeChunk* chunk, size_t new_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
  // Add a chunk to the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  void       addChunkToFreeLists(HeapWord* chunk, size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
  // Add a chunk to the free lists, preferring to suffix it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
  // to the last free chunk at end of space if possible, and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
  // updating the block census stats as well as block offset table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
  // Take any locks as appropriate if we are multithreaded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  void       addChunkToFreeListsAtEndRecordingStats(HeapWord* chunk, size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
  // Add a free chunk to the indexed free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
  void       returnChunkToFreeList(FreeChunk* chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
  // Add a free chunk to the dictionary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
  void       returnChunkToDictionary(FreeChunk* chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
  // Functions for maintaining the linear allocation buffers (LinAB).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
  // Repairing a linear allocation block refers to operations
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
  // performed on the remainder of a LinAB after an allocation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  // has been made from it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
  void       repairLinearAllocationBlocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  void       repairLinearAllocBlock(LinearAllocBlock* blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  void       refillLinearAllocBlock(LinearAllocBlock* blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  void       refillLinearAllocBlockIfNeeded(LinearAllocBlock* blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  void       refillLinearAllocBlocksIfNeeded();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
  void       verify_objects_initialized() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
  // Statistics reporting helper functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  void       reportFreeListStatistics() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
  void       reportIndexedFreeListStatistics() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
  size_t     maxChunkSizeInIndexedFreeLists() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
  size_t     numFreeBlocksInIndexedFreeLists() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  // Accessor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  HeapWord* unallocated_block() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
    HeapWord* ub = _bt.unallocated_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
    assert(ub >= bottom() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
           ub <= end(), "space invariant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
    return ub;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  void freed(HeapWord* start, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
    _bt.freed(start, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
 protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  // reset the indexed free list to its initial empty condition.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  void resetIndexedFreeListArray();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  // reset to an initial state with a single free block described
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  // by the MemRegion parameter.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  void reset(MemRegion mr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
  // Return the total number of words in the indexed free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  size_t     totalSizeInIndexedFreeLists() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  // Constructor...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  CompactibleFreeListSpace(BlockOffsetSharedArray* bs, MemRegion mr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
                           bool use_adaptive_freelists,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
                           FreeBlockDictionary::DictionaryChoice);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  // accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
  bool bestFitFirst() { return _fitStrategy == FreeBlockBestFitFirst; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
  FreeBlockDictionary* dictionary() const { return _dictionary; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  HeapWord* nearLargestChunk() const { return _nearLargestChunk; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  void set_nearLargestChunk(HeapWord* v) { _nearLargestChunk = v; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  // Return the free chunk at the end of the space.  If no such
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  // chunk exists, return NULL.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  FreeChunk* find_chunk_at_end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
  bool adaptive_freelists() { return _adaptive_freelists; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
  void set_collector(CMSCollector* collector) { _collector = collector; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  // Support for parallelization of rescan and marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  const size_t rescan_task_size()  const { return _rescan_task_size;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  const size_t marking_task_size() const { return _marking_task_size; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
  SequentialSubTasksDone* conc_par_seq_tasks() {return &_conc_par_seq_tasks; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  void initialize_sequential_subtasks_for_rescan(int n_threads);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
  void initialize_sequential_subtasks_for_marking(int n_threads,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
         HeapWord* low = NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
#if CFLS_LAB_REFILL_STATS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  void print_par_alloc_stats();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
  // Space enquiries
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  size_t used() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
  size_t free() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  size_t max_alloc_in_words() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
  // XXX: should have a less conservative used_region() than that of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  // Space; we could consider keeping track of highest allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  // address and correcting that at each sweep, as the sweeper
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  // goes through the entire allocated part of the generation. We
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  // could also use that information to keep the sweeper from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
  // sweeping more than is necessary. The allocator and sweeper will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
  // of course need to synchronize on this, since the sweeper will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
  // try to bump down the address and the allocator will try to bump it up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  // For now, however, we'll just use the default used_region()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  // which overestimates the region by returning the entire
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  // committed region (this is safe, but inefficient).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  // Returns a subregion of the space containing all the objects in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
  // the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  MemRegion used_region() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
    return MemRegion(bottom(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
                     BlockOffsetArrayUseUnallocatedBlock ?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
                     unallocated_block() : end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  // This is needed because the default implementation uses block_start()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
  // which can;t be used at certain times (for example phase 3 of mark-sweep).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  // A better fix is to change the assertions in phase 3 of mark-sweep to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
  // use is_in_reserved(), but that is deferred since the is_in() assertions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  // are buried through several layers of callers and are used elsewhere
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  // as well.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  bool is_in(const void* p) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
    return used_region().contains(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  virtual bool is_free_block(const HeapWord* p) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  // Resizing support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
  void set_end(HeapWord* value);  // override
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
  // mutual exclusion support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
  Mutex* freelistLock() const { return &_freelistLock; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  // Iteration support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
  void oop_iterate(MemRegion mr, OopClosure* cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  void oop_iterate(OopClosure* cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  void object_iterate(ObjectClosure* blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
  void object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
  // Requires that "mr" be entirely within the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
  // Apply "cl->do_object" to all objects that intersect with "mr".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
  // If the iteration encounters an unparseable portion of the region,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
  // terminate the iteration and return the address of the start of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  // subregion that isn't done.  Return of "NULL" indicates that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  // interation completed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
  virtual HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
       object_iterate_careful_m(MemRegion mr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
                                ObjectClosureCareful* cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
  virtual HeapWord*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
       object_iterate_careful(ObjectClosureCareful* cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
  // Override: provides a DCTO_CL specific to this kind of space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  DirtyCardToOopClosure* new_dcto_cl(OopClosure* cl,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
                                     CardTableModRefBS::PrecisionStyle precision,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
                                     HeapWord* boundary);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
  void blk_iterate(BlkClosure* cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  void blk_iterate_careful(BlkClosureCareful* cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
  HeapWord* block_start(const void* p) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
  HeapWord* block_start_careful(const void* p) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
  size_t block_size(const HeapWord* p) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
  size_t block_size_no_stall(HeapWord* p, const CMSCollector* c) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  bool block_is_obj(const HeapWord* p) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  bool obj_is_alive(const HeapWord* p) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  size_t block_size_nopar(const HeapWord* p) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  bool block_is_obj_nopar(const HeapWord* p) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  // iteration support for promotion
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  void save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  bool no_allocs_since_save_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  void object_iterate_since_last_GC(ObjectClosure* cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  // iteration support for sweeping
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  void save_sweep_limit() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
    _sweep_limit = BlockOffsetArrayUseUnallocatedBlock ?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
                   unallocated_block() : end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  NOT_PRODUCT(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
    void clear_sweep_limit() { _sweep_limit = NULL; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  HeapWord* sweep_limit() { return _sweep_limit; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  // Apply "blk->do_oop" to the addresses of all reference fields in objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  // promoted into this generation since the most recent save_marks() call.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  // Fields in objects allocated by applications of the closure
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  // *are* included in the iteration. Thus, when the iteration completes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  // there should be no further such objects remaining.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
  #define CFLS_OOP_SINCE_SAVE_MARKS_DECL(OopClosureType, nv_suffix)  \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
    void oop_since_save_marks_iterate##nv_suffix(OopClosureType* blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  ALL_SINCE_SAVE_MARKS_CLOSURES(CFLS_OOP_SINCE_SAVE_MARKS_DECL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
  #undef CFLS_OOP_SINCE_SAVE_MARKS_DECL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
  // Allocation support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
  HeapWord* allocate(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  HeapWord* par_allocate(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
  oop       promote(oop obj, size_t obj_size, oop* ref);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
  void      gc_prologue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
  void      gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  // This call is used by a containing CMS generation / collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
  // to inform the CFLS space that a sweep has been completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
  // and that the space can do any related house-keeping functions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
  void      sweep_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  // For an object in this space, the mark-word's two
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
  // LSB's having the value [11] indicates that it has been
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
  // promoted since the most recent call to save_marks() on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  // this generation and has not subsequently been iterated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
  // over (using oop_since_save_marks_iterate() above).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
  bool obj_allocated_since_save_marks(const oop obj) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
    assert(is_in_reserved(obj), "Wrong space?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
    return ((PromotedObject*)obj)->hasPromotedMark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
  // A worst-case estimate of the space required (in HeapWords) to expand the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
  // heap when promoting an obj of size obj_size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
  size_t expansionSpaceRequired(size_t obj_size) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  FreeChunk* allocateScratch(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  // returns true if either the small or large linear allocation buffer is empty.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
  bool       linearAllocationWouldFail();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
  // Adjust the chunk for the minimum size.  This version is called in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
  // most cases in CompactibleFreeListSpace methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
  inline static size_t adjustObjectSize(size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
    return (size_t) align_object_size(MAX2(size, (size_t)MinChunkSize));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
  // This is a virtual version of adjustObjectSize() that is called
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
  // only occasionally when the compaction space changes and the type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  // of the new compaction space is is only known to be CompactibleSpace.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  size_t adjust_object_size_v(size_t size) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
    return adjustObjectSize(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  // Minimum size of a free block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
  virtual size_t minimum_free_block_size() const { return MinChunkSize; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
  void      removeFreeChunkFromFreeLists(FreeChunk* chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
  void      addChunkAndRepairOffsetTable(HeapWord* chunk, size_t size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
              bool coalesced);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
  // Support for compaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
  void prepare_for_compaction(CompactPoint* cp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
  void adjust_pointers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  void compact();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
  // reset the space to reflect the fact that a compaction of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  // space has been done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
  virtual void reset_after_compaction();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
  // Debugging support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
  void print()                            const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
  void prepare_for_verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
  void verify(bool allow_dirty)           const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
  void verifyFreeLists()                  const PRODUCT_RETURN;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
  void verifyIndexedFreeLists()           const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
  void verifyIndexedFreeList(size_t size) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  // verify that the given chunk is in the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  bool verifyChunkInFreeLists(FreeChunk* fc) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
  // Do some basic checks on the the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
  void checkFreeListConsistency()         const PRODUCT_RETURN;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
  NOT_PRODUCT (
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
    void initializeIndexedFreeListArrayReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
    size_t sumIndexedFreeListArrayReturnedBytes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
    // Return the total number of chunks in the indexed free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
    size_t totalCountInIndexedFreeLists() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
    // Return the total numberof chunks in the space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
    size_t totalCount();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
  )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
  // The census consists of counts of the quantities such as
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  // the current count of the free chunks, number of chunks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
  // created as a result of the split of a larger chunk or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
  // coalescing of smaller chucks, etc.  The counts in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
  // census is used to make decisions on splitting and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
  // coalescing of chunks during the sweep of garbage.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
  // Print the statistics for the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
  void printFLCensus(int sweepCt)         const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  // Statistics functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
  // Initialize census for lists before the sweep.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
  void beginSweepFLCensus(float sweep_current,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
                          float sweep_estimate);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
  // Set the surplus for each of the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
  void setFLSurplus();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
  // Set the hint for each of the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
  void setFLHints();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
  // Clear the census for each of the free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
  void clearFLCensus();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
  // Perform functions for the census after the end of the sweep.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
  void endSweepFLCensus(int sweepCt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
  // Return true if the count of free chunks is greater
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
  // than the desired number of free chunks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
  bool coalOverPopulated(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
// Record (for each size):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
//   split-births = #chunks added due to splits in (prev-sweep-end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
//      this-sweep-start)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
//   split-deaths = #chunks removed for splits in (prev-sweep-end,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
//      this-sweep-start)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
//   num-curr     = #chunks at start of this sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
//   num-prev     = #chunks at end of previous sweep
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
// The above are quantities that are measured. Now define:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
//   num-desired := num-prev + split-births - split-deaths - num-curr
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
// Roughly, num-prev + split-births is the supply,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
// split-deaths is demand due to other sizes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
// and num-curr is what we have left.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
// Thus, num-desired is roughly speaking the "legitimate demand"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
// for blocks of this size and what we are striving to reach at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
// end of the current sweep.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
// For a given list, let num-len be its current population.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
// Define, for a free list of a given size:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
//   coal-overpopulated := num-len >= num-desired * coal-surplus
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
// (coal-surplus is set to 1.05, i.e. we allow a little slop when
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
// coalescing -- we do not coalesce unless we think that the current
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
// supply has exceeded the estimated demand by more than 5%).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
// For the set of sizes in the binary tree, which is neither dense nor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
// closed, it may be the case that for a particular size we have never
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
// had, or do not now have, or did not have at the previous sweep,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
// chunks of that size. We need to extend the definition of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
// coal-overpopulated to such sizes as well:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
//   For a chunk in/not in the binary tree, extend coal-overpopulated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
//   defined above to include all sizes as follows:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
//   . a size that is non-existent is coal-overpopulated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
//   . a size that has a num-desired <= 0 as defined above is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
//     coal-overpopulated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
// Also define, for a chunk heap-offset C and mountain heap-offset M:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
//   close-to-mountain := C >= 0.99 * M
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
// Now, the coalescing strategy is:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
//    Coalesce left-hand chunk with right-hand chunk if and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
//    only if:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
//      EITHER
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
//        . left-hand chunk is of a size that is coal-overpopulated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
//      OR
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
//        . right-hand chunk is close-to-mountain
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
  void smallCoalBirth(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
  void smallCoalDeath(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
  void coalBirth(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
  void coalDeath(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
  void smallSplitBirth(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
  void smallSplitDeath(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
  void splitBirth(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
  void splitDeath(size_t size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
  void split(size_t from, size_t to1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
  double flsFrag() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
// A parallel-GC-thread-local allocation buffer for allocation into a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
// CompactibleFreeListSpace.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
class CFLS_LAB : public CHeapObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
  // The space that this buffer allocates into.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
  CompactibleFreeListSpace* _cfls;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
  // Our local free lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
  FreeList _indexedFreeList[CompactibleFreeListSpace::IndexSetSize];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
  // Initialized from a command-line arg.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
  size_t _blocks_to_claim;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
#if CFLS_LAB_REFILL_STATS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
  // Some statistics.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
  int _refills;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
  int _blocksTaken;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
  static int _tot_refills;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
  static int _tot_blocksTaken;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
  static int _next_threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
  CFLS_LAB(CompactibleFreeListSpace* cfls);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
  // Allocate and return a block of the given size, or else return NULL.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
  HeapWord* alloc(size_t word_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
  // Return any unused portions of the buffer to the global pool.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
  void retire();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
size_t PromotionInfo::refillSize() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
  const size_t CMSSpoolBlockSize = 256;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
  const size_t sz = heap_word_size(sizeof(SpoolBlock) + sizeof(markOop)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
                                   * CMSSpoolBlockSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
  return CompactibleFreeListSpace::adjustObjectSize(sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
}