annotate src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp @ 1145:e018e6884bd8

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