src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp

Wed, 23 Dec 2009 09:23:54 -0800

author
ysr
date
Wed, 23 Dec 2009 09:23:54 -0800
changeset 1580
e018e6884bd8
parent 1014
0fbdb4381b99
child 1876
a8127dc669ba
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

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

mercurial