annotate src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp @ 452:00b023ae2d78

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