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