annotate src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp @ 1716:be3f9c242c9d

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