annotate src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @ 1489:cff162798819

6888953: some calls to function-like macros are missing semicolons Reviewed-by: pbk, kvn
author jcoomes
date Sun, 11 Oct 2009 16:19:25 -0700
parents 05b775309e59
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: 518
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 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_compactibleFreeListSpace.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 /////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
29 //// CompactibleFreeListSpace
a61af66fc99e Initial load
duke
parents:
diff changeset
30 /////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
31
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // highest ranked free list lock rank
a61af66fc99e Initial load
duke
parents:
diff changeset
33 int CompactibleFreeListSpace::_lockRank = Mutex::leaf + 3;
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // Constructor
a61af66fc99e Initial load
duke
parents:
diff changeset
36 CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs,
a61af66fc99e Initial load
duke
parents:
diff changeset
37 MemRegion mr, bool use_adaptive_freelists,
a61af66fc99e Initial load
duke
parents:
diff changeset
38 FreeBlockDictionary::DictionaryChoice dictionaryChoice) :
a61af66fc99e Initial load
duke
parents:
diff changeset
39 _dictionaryChoice(dictionaryChoice),
a61af66fc99e Initial load
duke
parents:
diff changeset
40 _adaptive_freelists(use_adaptive_freelists),
a61af66fc99e Initial load
duke
parents:
diff changeset
41 _bt(bs, mr),
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // free list locks are in the range of values taken by _lockRank
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // This range currently is [_leaf+2, _leaf+3]
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // Note: this requires that CFLspace c'tors
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // are called serially in the order in which the locks are
a61af66fc99e Initial load
duke
parents:
diff changeset
46 // are acquired in the program text. This is true today.
a61af66fc99e Initial load
duke
parents:
diff changeset
47 _freelistLock(_lockRank--, "CompactibleFreeListSpace._lock", true),
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _parDictionaryAllocLock(Mutex::leaf - 1, // == rank(ExpandHeap_lock) - 1
a61af66fc99e Initial load
duke
parents:
diff changeset
49 "CompactibleFreeListSpace._dict_par_lock", true),
a61af66fc99e Initial load
duke
parents:
diff changeset
50 _rescan_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord *
a61af66fc99e Initial load
duke
parents:
diff changeset
51 CMSRescanMultiple),
a61af66fc99e Initial load
duke
parents:
diff changeset
52 _marking_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord *
a61af66fc99e Initial load
duke
parents:
diff changeset
53 CMSConcMarkMultiple),
a61af66fc99e Initial load
duke
parents:
diff changeset
54 _collector(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
55 {
a61af66fc99e Initial load
duke
parents:
diff changeset
56 _bt.set_space(this);
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 187
diff changeset
57 initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // We have all of "mr", all of which we place in the dictionary
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // as one big chunk. We'll need to decide here which of several
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // possible alternative dictionary implementations to use. For
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // now the choice is easy, since we have only one working
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // implementation, namely, the simple binary tree (splaying
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // temporarily disabled).
a61af66fc99e Initial load
duke
parents:
diff changeset
64 switch (dictionaryChoice) {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 case FreeBlockDictionary::dictionarySplayTree:
a61af66fc99e Initial load
duke
parents:
diff changeset
66 case FreeBlockDictionary::dictionarySkipList:
a61af66fc99e Initial load
duke
parents:
diff changeset
67 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
68 warning("dictionaryChoice: selected option not understood; using"
a61af66fc99e Initial load
duke
parents:
diff changeset
69 " default BinaryTreeDictionary implementation instead.");
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
70 case FreeBlockDictionary::dictionaryBinaryTree:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
71 _dictionary = new BinaryTreeDictionary(mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
72 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
73 }
a61af66fc99e Initial load
duke
parents:
diff changeset
74 assert(_dictionary != NULL, "CMS dictionary initialization");
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // The indexed free lists are initially all empty and are lazily
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // filled in on demand. Initialize the array elements to NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
77 initializeIndexedFreeListArray();
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // Not using adaptive free lists assumes that allocation is first
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // from the linAB's. Also a cms perm gen which can be compacted
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // has to have the klass's klassKlass allocated at a lower
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // address in the heap than the klass so that the klassKlass is
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // moved to its new location before the klass is moved.
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // Set the _refillSize for the linear allocation blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
85 if (!use_adaptive_freelists) {
a61af66fc99e Initial load
duke
parents:
diff changeset
86 FreeChunk* fc = _dictionary->getChunk(mr.word_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // The small linAB initially has all the space and will allocate
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // a chunk of any size.
a61af66fc99e Initial load
duke
parents:
diff changeset
89 HeapWord* addr = (HeapWord*) fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
90 _smallLinearAllocBlock.set(addr, fc->size() ,
a61af66fc99e Initial load
duke
parents:
diff changeset
91 1024*SmallForLinearAlloc, fc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // Note that _unallocated_block is not updated here.
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // Allocations from the linear allocation block should
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // update it.
a61af66fc99e Initial load
duke
parents:
diff changeset
95 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 _smallLinearAllocBlock.set(0, 0, 1024*SmallForLinearAlloc,
a61af66fc99e Initial load
duke
parents:
diff changeset
97 SmallForLinearAlloc);
a61af66fc99e Initial load
duke
parents:
diff changeset
98 }
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // CMSIndexedFreeListReplenish should be at least 1
a61af66fc99e Initial load
duke
parents:
diff changeset
100 CMSIndexedFreeListReplenish = MAX2((uintx)1, CMSIndexedFreeListReplenish);
a61af66fc99e Initial load
duke
parents:
diff changeset
101 _promoInfo.setSpace(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
102 if (UseCMSBestFit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
103 _fitStrategy = FreeBlockBestFitFirst;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 _fitStrategy = FreeBlockStrategyNone;
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107 checkFreeListConsistency();
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // Initialize locks for parallel case.
a61af66fc99e Initial load
duke
parents:
diff changeset
110 if (ParallelGCThreads > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 _indexedFreeListParLocks[i] = new Mutex(Mutex::leaf - 1, // == ExpandHeap_lock - 1
a61af66fc99e Initial load
duke
parents:
diff changeset
113 "a freelist par lock",
a61af66fc99e Initial load
duke
parents:
diff changeset
114 true);
a61af66fc99e Initial load
duke
parents:
diff changeset
115 if (_indexedFreeListParLocks[i] == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
116 vm_exit_during_initialization("Could not allocate a par lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
117 DEBUG_ONLY(
a61af66fc99e Initial load
duke
parents:
diff changeset
118 _indexedFreeList[i].set_protecting_lock(_indexedFreeListParLocks[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 )
a61af66fc99e Initial load
duke
parents:
diff changeset
120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
121 _dictionary->set_par_lock(&_parDictionaryAllocLock);
a61af66fc99e Initial load
duke
parents:
diff changeset
122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // Like CompactibleSpace forward() but always calls cross_threshold() to
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // update the block offset table. Removed initialize_threshold call because
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // CFLS does not use a block offset array for contiguous spaces.
a61af66fc99e Initial load
duke
parents:
diff changeset
128 HeapWord* CompactibleFreeListSpace::forward(oop q, size_t size,
a61af66fc99e Initial load
duke
parents:
diff changeset
129 CompactPoint* cp, HeapWord* compact_top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // q is alive
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // First check if we should switch compaction space
a61af66fc99e Initial load
duke
parents:
diff changeset
132 assert(this == cp->space, "'this' should be current compaction space.");
a61af66fc99e Initial load
duke
parents:
diff changeset
133 size_t compaction_max_size = pointer_delta(end(), compact_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
134 assert(adjustObjectSize(size) == cp->space->adjust_object_size_v(size),
a61af66fc99e Initial load
duke
parents:
diff changeset
135 "virtual adjustObjectSize_v() method is not correct");
a61af66fc99e Initial load
duke
parents:
diff changeset
136 size_t adjusted_size = adjustObjectSize(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
137 assert(compaction_max_size >= MinChunkSize || compaction_max_size == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
138 "no small fragments allowed");
a61af66fc99e Initial load
duke
parents:
diff changeset
139 assert(minimum_free_block_size() == MinChunkSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
140 "for de-virtualized reference below");
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // Can't leave a nonzero size, residual fragment smaller than MinChunkSize
a61af66fc99e Initial load
duke
parents:
diff changeset
142 if (adjusted_size + MinChunkSize > compaction_max_size &&
a61af66fc99e Initial load
duke
parents:
diff changeset
143 adjusted_size != compaction_max_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // switch to next compaction space
a61af66fc99e Initial load
duke
parents:
diff changeset
146 cp->space->set_compaction_top(compact_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
147 cp->space = cp->space->next_compaction_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
148 if (cp->space == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 cp->gen = GenCollectedHeap::heap()->prev_gen(cp->gen);
a61af66fc99e Initial load
duke
parents:
diff changeset
150 assert(cp->gen != NULL, "compaction must succeed");
a61af66fc99e Initial load
duke
parents:
diff changeset
151 cp->space = cp->gen->first_compaction_space();
a61af66fc99e Initial load
duke
parents:
diff changeset
152 assert(cp->space != NULL, "generation must have a first compaction space");
a61af66fc99e Initial load
duke
parents:
diff changeset
153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
154 compact_top = cp->space->bottom();
a61af66fc99e Initial load
duke
parents:
diff changeset
155 cp->space->set_compaction_top(compact_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // The correct adjusted_size may not be the same as that for this method
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // (i.e., cp->space may no longer be "this" so adjust the size again.
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // Use the virtual method which is not used above to save the virtual
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // dispatch.
a61af66fc99e Initial load
duke
parents:
diff changeset
160 adjusted_size = cp->space->adjust_object_size_v(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
161 compaction_max_size = pointer_delta(cp->space->end(), compact_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
162 assert(cp->space->minimum_free_block_size() == 0, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
163 } while (adjusted_size > compaction_max_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // store the forwarding pointer into the mark word
a61af66fc99e Initial load
duke
parents:
diff changeset
167 if ((HeapWord*)q != compact_top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
168 q->forward_to(oop(compact_top));
a61af66fc99e Initial load
duke
parents:
diff changeset
169 assert(q->is_gc_marked(), "encoding the pointer should preserve the mark");
a61af66fc99e Initial load
duke
parents:
diff changeset
170 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // if the object isn't moving we can just set the mark to the default
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // mark and handle it specially later on.
a61af66fc99e Initial load
duke
parents:
diff changeset
173 q->init_mark();
a61af66fc99e Initial load
duke
parents:
diff changeset
174 assert(q->forwardee() == NULL, "should be forwarded to NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
176
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
177 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(q, adjusted_size));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
178 compact_top += adjusted_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // we need to update the offset table so that the beginnings of objects can be
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // found during scavenge. Note that we are updating the offset table based on
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // where the object will be once the compaction phase finishes.
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // Always call cross_threshold(). A contiguous space can only call it when
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // the compaction_top exceeds the current threshold but not for an
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // non-contiguous space.
a61af66fc99e Initial load
duke
parents:
diff changeset
187 cp->threshold =
a61af66fc99e Initial load
duke
parents:
diff changeset
188 cp->space->cross_threshold(compact_top - adjusted_size, compact_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
189 return compact_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // A modified copy of OffsetTableContigSpace::cross_threshold() with _offsets -> _bt
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // and use of single_block instead of alloc_block. The name here is not really
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // appropriate - maybe a more general name could be invented for both the
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // contiguous and noncontiguous spaces.
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 HeapWord* CompactibleFreeListSpace::cross_threshold(HeapWord* start, HeapWord* the_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
198 _bt.single_block(start, the_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
199 return end();
a61af66fc99e Initial load
duke
parents:
diff changeset
200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
201
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // Initialize them to NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
203 void CompactibleFreeListSpace::initializeIndexedFreeListArray() {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 for (size_t i = 0; i < IndexSetSize; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // Note that on platforms where objects are double word aligned,
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // the odd array elements are not used. It is convenient, however,
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // to map directly from the object size to the array element.
a61af66fc99e Initial load
duke
parents:
diff changeset
208 _indexedFreeList[i].reset(IndexSetSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 _indexedFreeList[i].set_size(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
210 assert(_indexedFreeList[i].count() == 0, "reset check failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
211 assert(_indexedFreeList[i].head() == NULL, "reset check failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
212 assert(_indexedFreeList[i].tail() == NULL, "reset check failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
213 assert(_indexedFreeList[i].hint() == IndexSetSize, "reset check failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 void CompactibleFreeListSpace::resetIndexedFreeListArray() {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 for (int i = 1; i < IndexSetSize; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 assert(_indexedFreeList[i].size() == (size_t) i,
a61af66fc99e Initial load
duke
parents:
diff changeset
220 "Indexed free list sizes are incorrect");
a61af66fc99e Initial load
duke
parents:
diff changeset
221 _indexedFreeList[i].reset(IndexSetSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 assert(_indexedFreeList[i].count() == 0, "reset check failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
223 assert(_indexedFreeList[i].head() == NULL, "reset check failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
224 assert(_indexedFreeList[i].tail() == NULL, "reset check failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
225 assert(_indexedFreeList[i].hint() == IndexSetSize, "reset check failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
228
a61af66fc99e Initial load
duke
parents:
diff changeset
229 void CompactibleFreeListSpace::reset(MemRegion mr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 resetIndexedFreeListArray();
a61af66fc99e Initial load
duke
parents:
diff changeset
231 dictionary()->reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
232 if (BlockOffsetArrayUseUnallocatedBlock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 assert(end() == mr.end(), "We are compacting to the bottom of CMS gen");
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // Everything's allocated until proven otherwise.
a61af66fc99e Initial load
duke
parents:
diff changeset
235 _bt.set_unallocated_block(end());
a61af66fc99e Initial load
duke
parents:
diff changeset
236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
237 if (!mr.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
238 assert(mr.word_size() >= MinChunkSize, "Chunk size is too small");
a61af66fc99e Initial load
duke
parents:
diff changeset
239 _bt.single_block(mr.start(), mr.word_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
240 FreeChunk* fc = (FreeChunk*) mr.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
241 fc->setSize(mr.word_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
242 if (mr.word_size() >= IndexSetSize ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
243 returnChunkToDictionary(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 _bt.verify_not_unallocated((HeapWord*)fc, fc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
246 _indexedFreeList[mr.word_size()].returnChunkAtHead(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
249 _promoInfo.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
250 _smallLinearAllocBlock._ptr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
251 _smallLinearAllocBlock._word_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
253
a61af66fc99e Initial load
duke
parents:
diff changeset
254 void CompactibleFreeListSpace::reset_after_compaction() {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // Reset the space to the new reality - one free chunk.
a61af66fc99e Initial load
duke
parents:
diff changeset
256 MemRegion mr(compaction_top(), end());
a61af66fc99e Initial load
duke
parents:
diff changeset
257 reset(mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // Now refill the linear allocation block(s) if possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
259 if (_adaptive_freelists) {
a61af66fc99e Initial load
duke
parents:
diff changeset
260 refillLinearAllocBlocksIfNeeded();
a61af66fc99e Initial load
duke
parents:
diff changeset
261 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // Place as much of mr in the linAB as we can get,
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // provided it was big enough to go into the dictionary.
a61af66fc99e Initial load
duke
parents:
diff changeset
264 FreeChunk* fc = dictionary()->findLargestDict();
a61af66fc99e Initial load
duke
parents:
diff changeset
265 if (fc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 assert(fc->size() == mr.word_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
267 "Why was the chunk broken up?");
a61af66fc99e Initial load
duke
parents:
diff changeset
268 removeChunkFromDictionary(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
269 HeapWord* addr = (HeapWord*) fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 _smallLinearAllocBlock.set(addr, fc->size() ,
a61af66fc99e Initial load
duke
parents:
diff changeset
271 1024*SmallForLinearAlloc, fc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // Note that _unallocated_block is not updated here.
a61af66fc99e Initial load
duke
parents:
diff changeset
273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
276
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // Walks the entire dictionary, returning a coterminal
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // chunk, if it exists. Use with caution since it involves
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // a potentially complete walk of a potentially large tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
280 FreeChunk* CompactibleFreeListSpace::find_chunk_at_end() {
a61af66fc99e Initial load
duke
parents:
diff changeset
281
a61af66fc99e Initial load
duke
parents:
diff changeset
282 assert_lock_strong(&_freelistLock);
a61af66fc99e Initial load
duke
parents:
diff changeset
283
a61af66fc99e Initial load
duke
parents:
diff changeset
284 return dictionary()->find_chunk_ends_at(end());
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286
a61af66fc99e Initial load
duke
parents:
diff changeset
287
a61af66fc99e Initial load
duke
parents:
diff changeset
288 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
289 void CompactibleFreeListSpace::initializeIndexedFreeListArrayReturnedBytes() {
a61af66fc99e Initial load
duke
parents:
diff changeset
290 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
291 _indexedFreeList[i].allocation_stats()->set_returnedBytes(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
294
a61af66fc99e Initial load
duke
parents:
diff changeset
295 size_t CompactibleFreeListSpace::sumIndexedFreeListArrayReturnedBytes() {
a61af66fc99e Initial load
duke
parents:
diff changeset
296 size_t sum = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
297 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
298 sum += _indexedFreeList[i].allocation_stats()->returnedBytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
300 return sum;
a61af66fc99e Initial load
duke
parents:
diff changeset
301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 size_t CompactibleFreeListSpace::totalCountInIndexedFreeLists() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 size_t count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
305 for (int i = MinChunkSize; i < IndexSetSize; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
306 debug_only(
a61af66fc99e Initial load
duke
parents:
diff changeset
307 ssize_t total_list_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
309 fc = fc->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 total_list_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
312 assert(total_list_count == _indexedFreeList[i].count(),
a61af66fc99e Initial load
duke
parents:
diff changeset
313 "Count in list is incorrect");
a61af66fc99e Initial load
duke
parents:
diff changeset
314 )
a61af66fc99e Initial load
duke
parents:
diff changeset
315 count += _indexedFreeList[i].count();
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 return count;
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 size_t CompactibleFreeListSpace::totalCount() {
a61af66fc99e Initial load
duke
parents:
diff changeset
321 size_t num = totalCountInIndexedFreeLists();
a61af66fc99e Initial load
duke
parents:
diff changeset
322 num += dictionary()->totalCount();
a61af66fc99e Initial load
duke
parents:
diff changeset
323 if (_smallLinearAllocBlock._word_size != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
324 num++;
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
326 return num;
a61af66fc99e Initial load
duke
parents:
diff changeset
327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
328 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
329
a61af66fc99e Initial load
duke
parents:
diff changeset
330 bool CompactibleFreeListSpace::is_free_block(const HeapWord* p) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
331 FreeChunk* fc = (FreeChunk*) p;
a61af66fc99e Initial load
duke
parents:
diff changeset
332 return fc->isFree();
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 size_t CompactibleFreeListSpace::used() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 return capacity() - free();
a61af66fc99e Initial load
duke
parents:
diff changeset
337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339 size_t CompactibleFreeListSpace::free() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // "MT-safe, but not MT-precise"(TM), if you will: i.e.
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // if you do this while the structures are in flux you
a61af66fc99e Initial load
duke
parents:
diff changeset
342 // may get an approximate answer only; for instance
a61af66fc99e Initial load
duke
parents:
diff changeset
343 // because there is concurrent allocation either
a61af66fc99e Initial load
duke
parents:
diff changeset
344 // directly by mutators or for promotion during a GC.
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // It's "MT-safe", however, in the sense that you are guaranteed
a61af66fc99e Initial load
duke
parents:
diff changeset
346 // not to crash and burn, for instance, because of walking
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // pointers that could disappear as you were walking them.
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // The approximation is because the various components
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // that are read below are not read atomically (and
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // further the computation of totalSizeInIndexedFreeLists()
a61af66fc99e Initial load
duke
parents:
diff changeset
351 // is itself a non-atomic computation. The normal use of
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // this is during a resize operation at the end of GC
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // and at that time you are guaranteed to get the
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // correct actual value. However, for instance, this is
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // also read completely asynchronously by the "perf-sampler"
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // that supports jvmstat, and you are apt to see the values
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // flicker in such cases.
a61af66fc99e Initial load
duke
parents:
diff changeset
358 assert(_dictionary != NULL, "No _dictionary?");
a61af66fc99e Initial load
duke
parents:
diff changeset
359 return (_dictionary->totalChunkSize(DEBUG_ONLY(freelistLock())) +
a61af66fc99e Initial load
duke
parents:
diff changeset
360 totalSizeInIndexedFreeLists() +
a61af66fc99e Initial load
duke
parents:
diff changeset
361 _smallLinearAllocBlock._word_size) * HeapWordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 size_t CompactibleFreeListSpace::max_alloc_in_words() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
365 assert(_dictionary != NULL, "No _dictionary?");
a61af66fc99e Initial load
duke
parents:
diff changeset
366 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
367 size_t res = _dictionary->maxChunkSize();
a61af66fc99e Initial load
duke
parents:
diff changeset
368 res = MAX2(res, MIN2(_smallLinearAllocBlock._word_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
369 (size_t) SmallForLinearAlloc - 1));
a61af66fc99e Initial load
duke
parents:
diff changeset
370 // XXX the following could potentially be pretty slow;
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // should one, pesimally for the rare cases when res
a61af66fc99e Initial load
duke
parents:
diff changeset
372 // caclulated above is less than IndexSetSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // just return res calculated above? My reasoning was that
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // those cases will be so rare that the extra time spent doesn't
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // really matter....
a61af66fc99e Initial load
duke
parents:
diff changeset
376 // Note: do not change the loop test i >= res + IndexSetStride
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // to i > res below, because i is unsigned and res may be zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
378 for (size_t i = IndexSetSize - 1; i >= res + IndexSetStride;
a61af66fc99e Initial load
duke
parents:
diff changeset
379 i -= IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 if (_indexedFreeList[i].head() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 assert(_indexedFreeList[i].count() != 0, "Inconsistent FreeList");
a61af66fc99e Initial load
duke
parents:
diff changeset
382 return i;
a61af66fc99e Initial load
duke
parents:
diff changeset
383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
385 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
387
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
388 void CompactibleFreeListSpace::print_indexed_free_lists(outputStream* st)
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
389 const {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
390 reportIndexedFreeListStatistics();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
391 gclog_or_tty->print_cr("Layout of Indexed Freelists");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
392 gclog_or_tty->print_cr("---------------------------");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
393 FreeList::print_labels_on(st, "size");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
394 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
395 _indexedFreeList[i].print_on(gclog_or_tty);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
396 for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
397 fc = fc->next()) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
398 gclog_or_tty->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s",
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
399 fc, (HeapWord*)fc + i,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
400 fc->cantCoalesce() ? "\t CC" : "");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
401 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
402 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
403 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
404
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
405 void CompactibleFreeListSpace::print_promo_info_blocks(outputStream* st)
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
406 const {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
407 _promoInfo.print_on(st);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
408 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
409
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
410 void CompactibleFreeListSpace::print_dictionary_free_lists(outputStream* st)
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
411 const {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
412 _dictionary->reportStatistics();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
413 st->print_cr("Layout of Freelists in Tree");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
414 st->print_cr("---------------------------");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
415 _dictionary->print_free_lists(st);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
416 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
417
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
418 class BlkPrintingClosure: public BlkClosure {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
419 const CMSCollector* _collector;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
420 const CompactibleFreeListSpace* _sp;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
421 const CMSBitMap* _live_bit_map;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
422 const bool _post_remark;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
423 outputStream* _st;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
424 public:
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
425 BlkPrintingClosure(const CMSCollector* collector,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
426 const CompactibleFreeListSpace* sp,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
427 const CMSBitMap* live_bit_map,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
428 outputStream* st):
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
429 _collector(collector),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
430 _sp(sp),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
431 _live_bit_map(live_bit_map),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
432 _post_remark(collector->abstract_state() > CMSCollector::FinalMarking),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
433 _st(st) { }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
434 size_t do_blk(HeapWord* addr);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
435 };
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
436
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
437 size_t BlkPrintingClosure::do_blk(HeapWord* addr) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
438 size_t sz = _sp->block_size_no_stall(addr, _collector);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
439 assert(sz != 0, "Should always be able to compute a size");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
440 if (_sp->block_is_obj(addr)) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
441 const bool dead = _post_remark && !_live_bit_map->isMarked(addr);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
442 _st->print_cr(PTR_FORMAT ": %s object of size " SIZE_FORMAT "%s",
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
443 addr,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
444 dead ? "dead" : "live",
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
445 sz,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
446 (!dead && CMSPrintObjectsInDump) ? ":" : ".");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
447 if (CMSPrintObjectsInDump && !dead) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
448 oop(addr)->print_on(_st);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
449 _st->print_cr("--------------------------------------");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
450 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
451 } else { // free block
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
452 _st->print_cr(PTR_FORMAT ": free block of size " SIZE_FORMAT "%s",
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
453 addr, sz, CMSPrintChunksInDump ? ":" : ".");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
454 if (CMSPrintChunksInDump) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
455 ((FreeChunk*)addr)->print_on(_st);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
456 _st->print_cr("--------------------------------------");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
457 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
458 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
459 return sz;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
460 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
461
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
462 void CompactibleFreeListSpace::dump_at_safepoint_with_locks(CMSCollector* c,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
463 outputStream* st) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
464 st->print_cr("\n=========================");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
465 st->print_cr("Block layout in CMS Heap:");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
466 st->print_cr("=========================");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
467 BlkPrintingClosure bpcl(c, this, c->markBitMap(), st);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
468 blk_iterate(&bpcl);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
469
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
470 st->print_cr("\n=======================================");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
471 st->print_cr("Order & Layout of Promotion Info Blocks");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
472 st->print_cr("=======================================");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
473 print_promo_info_blocks(st);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
474
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
475 st->print_cr("\n===========================");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
476 st->print_cr("Order of Indexed Free Lists");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
477 st->print_cr("=========================");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
478 print_indexed_free_lists(st);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
479
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
480 st->print_cr("\n=================================");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
481 st->print_cr("Order of Free Lists in Dictionary");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
482 st->print_cr("=================================");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
483 print_dictionary_free_lists(st);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
484 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
485
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
486
0
a61af66fc99e Initial load
duke
parents:
diff changeset
487 void CompactibleFreeListSpace::reportFreeListStatistics() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
488 assert_lock_strong(&_freelistLock);
a61af66fc99e Initial load
duke
parents:
diff changeset
489 assert(PrintFLSStatistics != 0, "Reporting error");
a61af66fc99e Initial load
duke
parents:
diff changeset
490 _dictionary->reportStatistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
491 if (PrintFLSStatistics > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
492 reportIndexedFreeListStatistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
493 size_t totalSize = totalSizeInIndexedFreeLists() +
a61af66fc99e Initial load
duke
parents:
diff changeset
494 _dictionary->totalChunkSize(DEBUG_ONLY(freelistLock()));
a61af66fc99e Initial load
duke
parents:
diff changeset
495 gclog_or_tty->print(" free=%ld frag=%1.4f\n", totalSize, flsFrag());
a61af66fc99e Initial load
duke
parents:
diff changeset
496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
497 }
a61af66fc99e Initial load
duke
parents:
diff changeset
498
a61af66fc99e Initial load
duke
parents:
diff changeset
499 void CompactibleFreeListSpace::reportIndexedFreeListStatistics() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
500 assert_lock_strong(&_freelistLock);
a61af66fc99e Initial load
duke
parents:
diff changeset
501 gclog_or_tty->print("Statistics for IndexedFreeLists:\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
502 "--------------------------------\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
503 size_t totalSize = totalSizeInIndexedFreeLists();
a61af66fc99e Initial load
duke
parents:
diff changeset
504 size_t freeBlocks = numFreeBlocksInIndexedFreeLists();
a61af66fc99e Initial load
duke
parents:
diff changeset
505 gclog_or_tty->print("Total Free Space: %d\n", totalSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
506 gclog_or_tty->print("Max Chunk Size: %d\n", maxChunkSizeInIndexedFreeLists());
a61af66fc99e Initial load
duke
parents:
diff changeset
507 gclog_or_tty->print("Number of Blocks: %d\n", freeBlocks);
a61af66fc99e Initial load
duke
parents:
diff changeset
508 if (freeBlocks != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 gclog_or_tty->print("Av. Block Size: %d\n", totalSize/freeBlocks);
a61af66fc99e Initial load
duke
parents:
diff changeset
510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 size_t CompactibleFreeListSpace::numFreeBlocksInIndexedFreeLists() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
514 size_t res = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
515 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
516 debug_only(
a61af66fc99e Initial load
duke
parents:
diff changeset
517 ssize_t recount = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
518 for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
519 fc = fc->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
520 recount += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522 assert(recount == _indexedFreeList[i].count(),
a61af66fc99e Initial load
duke
parents:
diff changeset
523 "Incorrect count in list");
a61af66fc99e Initial load
duke
parents:
diff changeset
524 )
a61af66fc99e Initial load
duke
parents:
diff changeset
525 res += _indexedFreeList[i].count();
a61af66fc99e Initial load
duke
parents:
diff changeset
526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
527 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
529
a61af66fc99e Initial load
duke
parents:
diff changeset
530 size_t CompactibleFreeListSpace::maxChunkSizeInIndexedFreeLists() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 for (size_t i = IndexSetSize - 1; i != 0; i -= IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 if (_indexedFreeList[i].head() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
533 assert(_indexedFreeList[i].count() != 0, "Inconsistent FreeList");
a61af66fc99e Initial load
duke
parents:
diff changeset
534 return (size_t)i;
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
537 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
539
a61af66fc99e Initial load
duke
parents:
diff changeset
540 void CompactibleFreeListSpace::set_end(HeapWord* value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
541 HeapWord* prevEnd = end();
a61af66fc99e Initial load
duke
parents:
diff changeset
542 assert(prevEnd != value, "unnecessary set_end call");
a61af66fc99e Initial load
duke
parents:
diff changeset
543 assert(prevEnd == NULL || value >= unallocated_block(), "New end is below unallocated block");
a61af66fc99e Initial load
duke
parents:
diff changeset
544 _end = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
545 if (prevEnd != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // Resize the underlying block offset table.
a61af66fc99e Initial load
duke
parents:
diff changeset
547 _bt.resize(pointer_delta(value, bottom()));
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
548 if (value <= prevEnd) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
549 assert(value >= unallocated_block(), "New end is below unallocated block");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
550 } else {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
551 // Now, take this new chunk and add it to the free blocks.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
552 // Note that the BOT has not yet been updated for this block.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
553 size_t newFcSize = pointer_delta(value, prevEnd);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
554 // XXX This is REALLY UGLY and should be fixed up. XXX
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
555 if (!_adaptive_freelists && _smallLinearAllocBlock._ptr == NULL) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
556 // Mark the boundary of the new block in BOT
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
557 _bt.mark_block(prevEnd, value);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
558 // put it all in the linAB
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
559 if (ParallelGCThreads == 0) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
560 _smallLinearAllocBlock._ptr = prevEnd;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
561 _smallLinearAllocBlock._word_size = newFcSize;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
562 repairLinearAllocBlock(&_smallLinearAllocBlock);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
563 } else { // ParallelGCThreads > 0
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
564 MutexLockerEx x(parDictionaryAllocLock(),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
565 Mutex::_no_safepoint_check_flag);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
566 _smallLinearAllocBlock._ptr = prevEnd;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
567 _smallLinearAllocBlock._word_size = newFcSize;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
568 repairLinearAllocBlock(&_smallLinearAllocBlock);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
569 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
570 // Births of chunks put into a LinAB are not recorded. Births
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
571 // of chunks as they are allocated out of a LinAB are.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
572 } else {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
573 // Add the block to the free lists, if possible coalescing it
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
574 // with the last free block, and update the BOT and census data.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
575 addChunkToFreeListsAtEndRecordingStats(prevEnd, newFcSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
576 }
a61af66fc99e Initial load
duke
parents:
diff changeset
577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
580
a61af66fc99e Initial load
duke
parents:
diff changeset
581 class FreeListSpace_DCTOC : public Filtering_DCTOC {
a61af66fc99e Initial load
duke
parents:
diff changeset
582 CompactibleFreeListSpace* _cfls;
a61af66fc99e Initial load
duke
parents:
diff changeset
583 CMSCollector* _collector;
a61af66fc99e Initial load
duke
parents:
diff changeset
584 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // Override.
a61af66fc99e Initial load
duke
parents:
diff changeset
586 #define walk_mem_region_with_cl_DECL(ClosureType) \
a61af66fc99e Initial load
duke
parents:
diff changeset
587 virtual void walk_mem_region_with_cl(MemRegion mr, \
a61af66fc99e Initial load
duke
parents:
diff changeset
588 HeapWord* bottom, HeapWord* top, \
a61af66fc99e Initial load
duke
parents:
diff changeset
589 ClosureType* cl); \
a61af66fc99e Initial load
duke
parents:
diff changeset
590 void walk_mem_region_with_cl_par(MemRegion mr, \
a61af66fc99e Initial load
duke
parents:
diff changeset
591 HeapWord* bottom, HeapWord* top, \
a61af66fc99e Initial load
duke
parents:
diff changeset
592 ClosureType* cl); \
a61af66fc99e Initial load
duke
parents:
diff changeset
593 void walk_mem_region_with_cl_nopar(MemRegion mr, \
a61af66fc99e Initial load
duke
parents:
diff changeset
594 HeapWord* bottom, HeapWord* top, \
a61af66fc99e Initial load
duke
parents:
diff changeset
595 ClosureType* cl)
a61af66fc99e Initial load
duke
parents:
diff changeset
596 walk_mem_region_with_cl_DECL(OopClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
597 walk_mem_region_with_cl_DECL(FilteringClosure);
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
600 FreeListSpace_DCTOC(CompactibleFreeListSpace* sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
601 CMSCollector* collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
602 OopClosure* cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
603 CardTableModRefBS::PrecisionStyle precision,
a61af66fc99e Initial load
duke
parents:
diff changeset
604 HeapWord* boundary) :
a61af66fc99e Initial load
duke
parents:
diff changeset
605 Filtering_DCTOC(sp, cl, precision, boundary),
a61af66fc99e Initial load
duke
parents:
diff changeset
606 _cfls(sp), _collector(collector) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
607 };
a61af66fc99e Initial load
duke
parents:
diff changeset
608
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // We de-virtualize the block-related calls below, since we know that our
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // space is a CompactibleFreeListSpace.
a61af66fc99e Initial load
duke
parents:
diff changeset
611 #define FreeListSpace_DCTOC__walk_mem_region_with_cl_DEFN(ClosureType) \
a61af66fc99e Initial load
duke
parents:
diff changeset
612 void FreeListSpace_DCTOC::walk_mem_region_with_cl(MemRegion mr, \
a61af66fc99e Initial load
duke
parents:
diff changeset
613 HeapWord* bottom, \
a61af66fc99e Initial load
duke
parents:
diff changeset
614 HeapWord* top, \
a61af66fc99e Initial load
duke
parents:
diff changeset
615 ClosureType* cl) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
616 if (SharedHeap::heap()->n_par_threads() > 0) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
617 walk_mem_region_with_cl_par(mr, bottom, top, cl); \
a61af66fc99e Initial load
duke
parents:
diff changeset
618 } else { \
a61af66fc99e Initial load
duke
parents:
diff changeset
619 walk_mem_region_with_cl_nopar(mr, bottom, top, cl); \
a61af66fc99e Initial load
duke
parents:
diff changeset
620 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
621 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
622 void FreeListSpace_DCTOC::walk_mem_region_with_cl_par(MemRegion mr, \
a61af66fc99e Initial load
duke
parents:
diff changeset
623 HeapWord* bottom, \
a61af66fc99e Initial load
duke
parents:
diff changeset
624 HeapWord* top, \
a61af66fc99e Initial load
duke
parents:
diff changeset
625 ClosureType* cl) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
626 /* Skip parts that are before "mr", in case "block_start" sent us \
a61af66fc99e Initial load
duke
parents:
diff changeset
627 back too far. */ \
a61af66fc99e Initial load
duke
parents:
diff changeset
628 HeapWord* mr_start = mr.start(); \
a61af66fc99e Initial load
duke
parents:
diff changeset
629 size_t bot_size = _cfls->CompactibleFreeListSpace::block_size(bottom); \
a61af66fc99e Initial load
duke
parents:
diff changeset
630 HeapWord* next = bottom + bot_size; \
a61af66fc99e Initial load
duke
parents:
diff changeset
631 while (next < mr_start) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
632 bottom = next; \
a61af66fc99e Initial load
duke
parents:
diff changeset
633 bot_size = _cfls->CompactibleFreeListSpace::block_size(bottom); \
a61af66fc99e Initial load
duke
parents:
diff changeset
634 next = bottom + bot_size; \
a61af66fc99e Initial load
duke
parents:
diff changeset
635 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
636 \
a61af66fc99e Initial load
duke
parents:
diff changeset
637 while (bottom < top) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
638 if (_cfls->CompactibleFreeListSpace::block_is_obj(bottom) && \
a61af66fc99e Initial load
duke
parents:
diff changeset
639 !_cfls->CompactibleFreeListSpace::obj_allocated_since_save_marks( \
a61af66fc99e Initial load
duke
parents:
diff changeset
640 oop(bottom)) && \
a61af66fc99e Initial load
duke
parents:
diff changeset
641 !_collector->CMSCollector::is_dead_obj(oop(bottom))) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
642 size_t word_sz = oop(bottom)->oop_iterate(cl, mr); \
a61af66fc99e Initial load
duke
parents:
diff changeset
643 bottom += _cfls->adjustObjectSize(word_sz); \
a61af66fc99e Initial load
duke
parents:
diff changeset
644 } else { \
a61af66fc99e Initial load
duke
parents:
diff changeset
645 bottom += _cfls->CompactibleFreeListSpace::block_size(bottom); \
a61af66fc99e Initial load
duke
parents:
diff changeset
646 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
647 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
648 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
649 void FreeListSpace_DCTOC::walk_mem_region_with_cl_nopar(MemRegion mr, \
a61af66fc99e Initial load
duke
parents:
diff changeset
650 HeapWord* bottom, \
a61af66fc99e Initial load
duke
parents:
diff changeset
651 HeapWord* top, \
a61af66fc99e Initial load
duke
parents:
diff changeset
652 ClosureType* cl) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
653 /* Skip parts that are before "mr", in case "block_start" sent us \
a61af66fc99e Initial load
duke
parents:
diff changeset
654 back too far. */ \
a61af66fc99e Initial load
duke
parents:
diff changeset
655 HeapWord* mr_start = mr.start(); \
a61af66fc99e Initial load
duke
parents:
diff changeset
656 size_t bot_size = _cfls->CompactibleFreeListSpace::block_size_nopar(bottom); \
a61af66fc99e Initial load
duke
parents:
diff changeset
657 HeapWord* next = bottom + bot_size; \
a61af66fc99e Initial load
duke
parents:
diff changeset
658 while (next < mr_start) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
659 bottom = next; \
a61af66fc99e Initial load
duke
parents:
diff changeset
660 bot_size = _cfls->CompactibleFreeListSpace::block_size_nopar(bottom); \
a61af66fc99e Initial load
duke
parents:
diff changeset
661 next = bottom + bot_size; \
a61af66fc99e Initial load
duke
parents:
diff changeset
662 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
663 \
a61af66fc99e Initial load
duke
parents:
diff changeset
664 while (bottom < top) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
665 if (_cfls->CompactibleFreeListSpace::block_is_obj_nopar(bottom) && \
a61af66fc99e Initial load
duke
parents:
diff changeset
666 !_cfls->CompactibleFreeListSpace::obj_allocated_since_save_marks( \
a61af66fc99e Initial load
duke
parents:
diff changeset
667 oop(bottom)) && \
a61af66fc99e Initial load
duke
parents:
diff changeset
668 !_collector->CMSCollector::is_dead_obj(oop(bottom))) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
669 size_t word_sz = oop(bottom)->oop_iterate(cl, mr); \
a61af66fc99e Initial load
duke
parents:
diff changeset
670 bottom += _cfls->adjustObjectSize(word_sz); \
a61af66fc99e Initial load
duke
parents:
diff changeset
671 } else { \
a61af66fc99e Initial load
duke
parents:
diff changeset
672 bottom += _cfls->CompactibleFreeListSpace::block_size_nopar(bottom); \
a61af66fc99e Initial load
duke
parents:
diff changeset
673 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
674 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
676
a61af66fc99e Initial load
duke
parents:
diff changeset
677 // (There are only two of these, rather than N, because the split is due
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // only to the introduction of the FilteringClosure, a local part of the
a61af66fc99e Initial load
duke
parents:
diff changeset
679 // impl of this abstraction.)
a61af66fc99e Initial load
duke
parents:
diff changeset
680 FreeListSpace_DCTOC__walk_mem_region_with_cl_DEFN(OopClosure)
a61af66fc99e Initial load
duke
parents:
diff changeset
681 FreeListSpace_DCTOC__walk_mem_region_with_cl_DEFN(FilteringClosure)
a61af66fc99e Initial load
duke
parents:
diff changeset
682
a61af66fc99e Initial load
duke
parents:
diff changeset
683 DirtyCardToOopClosure*
a61af66fc99e Initial load
duke
parents:
diff changeset
684 CompactibleFreeListSpace::new_dcto_cl(OopClosure* cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
685 CardTableModRefBS::PrecisionStyle precision,
a61af66fc99e Initial load
duke
parents:
diff changeset
686 HeapWord* boundary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
687 return new FreeListSpace_DCTOC(this, _collector, cl, precision, boundary);
a61af66fc99e Initial load
duke
parents:
diff changeset
688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
689
a61af66fc99e Initial load
duke
parents:
diff changeset
690
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // Note on locking for the space iteration functions:
a61af66fc99e Initial load
duke
parents:
diff changeset
692 // since the collector's iteration activities are concurrent with
a61af66fc99e Initial load
duke
parents:
diff changeset
693 // allocation activities by mutators, absent a suitable mutual exclusion
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // mechanism the iterators may go awry. For instace a block being iterated
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // may suddenly be allocated or divided up and part of it allocated and
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // so on.
a61af66fc99e Initial load
duke
parents:
diff changeset
697
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // Apply the given closure to each block in the space.
a61af66fc99e Initial load
duke
parents:
diff changeset
699 void CompactibleFreeListSpace::blk_iterate_careful(BlkClosureCareful* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
700 assert_lock_strong(freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
701 HeapWord *cur, *limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
702 for (cur = bottom(), limit = end(); cur < limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
703 cur += cl->do_blk_careful(cur));
a61af66fc99e Initial load
duke
parents:
diff changeset
704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 // Apply the given closure to each block in the space.
a61af66fc99e Initial load
duke
parents:
diff changeset
707 void CompactibleFreeListSpace::blk_iterate(BlkClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
708 assert_lock_strong(freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
709 HeapWord *cur, *limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
710 for (cur = bottom(), limit = end(); cur < limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
711 cur += cl->do_blk(cur));
a61af66fc99e Initial load
duke
parents:
diff changeset
712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // Apply the given closure to each oop in the space.
a61af66fc99e Initial load
duke
parents:
diff changeset
715 void CompactibleFreeListSpace::oop_iterate(OopClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
716 assert_lock_strong(freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
717 HeapWord *cur, *limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
718 size_t curSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
719 for (cur = bottom(), limit = end(); cur < limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
720 cur += curSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
721 curSize = block_size(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
722 if (block_is_obj(cur)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
723 oop(cur)->oop_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
726 }
a61af66fc99e Initial load
duke
parents:
diff changeset
727
a61af66fc99e Initial load
duke
parents:
diff changeset
728 // Apply the given closure to each oop in the space \intersect memory region.
a61af66fc99e Initial load
duke
parents:
diff changeset
729 void CompactibleFreeListSpace::oop_iterate(MemRegion mr, OopClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
730 assert_lock_strong(freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
731 if (is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
732 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
734 MemRegion cur = MemRegion(bottom(), end());
a61af66fc99e Initial load
duke
parents:
diff changeset
735 mr = mr.intersection(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
736 if (mr.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
737 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
739 if (mr.equals(cur)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
740 oop_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
741 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
742 }
a61af66fc99e Initial load
duke
parents:
diff changeset
743 assert(mr.end() <= end(), "just took an intersection above");
a61af66fc99e Initial load
duke
parents:
diff changeset
744 HeapWord* obj_addr = block_start(mr.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
745 HeapWord* t = mr.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
746
a61af66fc99e Initial load
duke
parents:
diff changeset
747 SpaceMemRegionOopsIterClosure smr_blk(cl, mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
748 if (block_is_obj(obj_addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
749 // Handle first object specially.
a61af66fc99e Initial load
duke
parents:
diff changeset
750 oop obj = oop(obj_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
751 obj_addr += adjustObjectSize(obj->oop_iterate(&smr_blk));
a61af66fc99e Initial load
duke
parents:
diff changeset
752 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
753 FreeChunk* fc = (FreeChunk*)obj_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
754 obj_addr += fc->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
755 }
a61af66fc99e Initial load
duke
parents:
diff changeset
756 while (obj_addr < t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
757 HeapWord* obj = obj_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
758 obj_addr += block_size(obj_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
759 // If "obj_addr" is not greater than top, then the
a61af66fc99e Initial load
duke
parents:
diff changeset
760 // entire object "obj" is within the region.
a61af66fc99e Initial load
duke
parents:
diff changeset
761 if (obj_addr <= t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
762 if (block_is_obj(obj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
763 oop(obj)->oop_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
765 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
766 // "obj" extends beyond end of region
a61af66fc99e Initial load
duke
parents:
diff changeset
767 if (block_is_obj(obj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
768 oop(obj)->oop_iterate(&smr_blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
769 }
a61af66fc99e Initial load
duke
parents:
diff changeset
770 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
772 }
a61af66fc99e Initial load
duke
parents:
diff changeset
773 }
a61af66fc99e Initial load
duke
parents:
diff changeset
774
a61af66fc99e Initial load
duke
parents:
diff changeset
775 // NOTE: In the following methods, in order to safely be able to
a61af66fc99e Initial load
duke
parents:
diff changeset
776 // apply the closure to an object, we need to be sure that the
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // object has been initialized. We are guaranteed that an object
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // is initialized if we are holding the Heap_lock with the
a61af66fc99e Initial load
duke
parents:
diff changeset
779 // world stopped.
a61af66fc99e Initial load
duke
parents:
diff changeset
780 void CompactibleFreeListSpace::verify_objects_initialized() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
781 if (is_init_completed()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
782 assert_locked_or_safepoint(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
783 if (Universe::is_fully_initialized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
784 guarantee(SafepointSynchronize::is_at_safepoint(),
a61af66fc99e Initial load
duke
parents:
diff changeset
785 "Required for objects to be initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
786 }
a61af66fc99e Initial load
duke
parents:
diff changeset
787 } // else make a concession at vm start-up
a61af66fc99e Initial load
duke
parents:
diff changeset
788 }
a61af66fc99e Initial load
duke
parents:
diff changeset
789
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // Apply the given closure to each object in the space
a61af66fc99e Initial load
duke
parents:
diff changeset
791 void CompactibleFreeListSpace::object_iterate(ObjectClosure* blk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
792 assert_lock_strong(freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
793 NOT_PRODUCT(verify_objects_initialized());
a61af66fc99e Initial load
duke
parents:
diff changeset
794 HeapWord *cur, *limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
795 size_t curSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
796 for (cur = bottom(), limit = end(); cur < limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
797 cur += curSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
798 curSize = block_size(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
799 if (block_is_obj(cur)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
800 blk->do_object(oop(cur));
a61af66fc99e Initial load
duke
parents:
diff changeset
801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804
517
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
805 // Apply the given closure to each live object in the space
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
806 // The usage of CompactibleFreeListSpace
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
807 // by the ConcurrentMarkSweepGeneration for concurrent GC's allows
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
808 // objects in the space with references to objects that are no longer
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
809 // valid. For example, an object may reference another object
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
810 // that has already been sweep up (collected). This method uses
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
811 // obj_is_alive() to determine whether it is safe to apply the closure to
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
812 // an object. See obj_is_alive() for details on how liveness of an
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
813 // object is decided.
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
814
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
815 void CompactibleFreeListSpace::safe_object_iterate(ObjectClosure* blk) {
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
816 assert_lock_strong(freelistLock());
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
817 NOT_PRODUCT(verify_objects_initialized());
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
818 HeapWord *cur, *limit;
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
819 size_t curSize;
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
820 for (cur = bottom(), limit = end(); cur < limit;
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
821 cur += curSize) {
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
822 curSize = block_size(cur);
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
823 if (block_is_obj(cur) && obj_is_alive(cur)) {
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
824 blk->do_object(oop(cur));
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
825 }
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
826 }
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
827 }
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 360
diff changeset
828
0
a61af66fc99e Initial load
duke
parents:
diff changeset
829 void CompactibleFreeListSpace::object_iterate_mem(MemRegion mr,
a61af66fc99e Initial load
duke
parents:
diff changeset
830 UpwardsObjectClosure* cl) {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
831 assert_locked(freelistLock());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
832 NOT_PRODUCT(verify_objects_initialized());
a61af66fc99e Initial load
duke
parents:
diff changeset
833 Space::object_iterate_mem(mr, cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
834 }
a61af66fc99e Initial load
duke
parents:
diff changeset
835
a61af66fc99e Initial load
duke
parents:
diff changeset
836 // Callers of this iterator beware: The closure application should
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // be robust in the face of uninitialized objects and should (always)
a61af66fc99e Initial load
duke
parents:
diff changeset
838 // return a correct size so that the next addr + size below gives us a
a61af66fc99e Initial load
duke
parents:
diff changeset
839 // valid block boundary. [See for instance,
a61af66fc99e Initial load
duke
parents:
diff changeset
840 // ScanMarkedObjectsAgainCarefullyClosure::do_object_careful()
a61af66fc99e Initial load
duke
parents:
diff changeset
841 // in ConcurrentMarkSweepGeneration.cpp.]
a61af66fc99e Initial load
duke
parents:
diff changeset
842 HeapWord*
a61af66fc99e Initial load
duke
parents:
diff changeset
843 CompactibleFreeListSpace::object_iterate_careful(ObjectClosureCareful* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
844 assert_lock_strong(freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
845 HeapWord *addr, *last;
a61af66fc99e Initial load
duke
parents:
diff changeset
846 size_t size;
a61af66fc99e Initial load
duke
parents:
diff changeset
847 for (addr = bottom(), last = end();
a61af66fc99e Initial load
duke
parents:
diff changeset
848 addr < last; addr += size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
849 FreeChunk* fc = (FreeChunk*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
850 if (fc->isFree()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 // Since we hold the free list lock, which protects direct
a61af66fc99e Initial load
duke
parents:
diff changeset
852 // allocation in this generation by mutators, a free object
a61af66fc99e Initial load
duke
parents:
diff changeset
853 // will remain free throughout this iteration code.
a61af66fc99e Initial load
duke
parents:
diff changeset
854 size = fc->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
855 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
856 // Note that the object need not necessarily be initialized,
a61af66fc99e Initial load
duke
parents:
diff changeset
857 // because (for instance) the free list lock does NOT protect
a61af66fc99e Initial load
duke
parents:
diff changeset
858 // object initialization. The closure application below must
a61af66fc99e Initial load
duke
parents:
diff changeset
859 // therefore be correct in the face of uninitialized objects.
a61af66fc99e Initial load
duke
parents:
diff changeset
860 size = cl->do_object_careful(oop(addr));
a61af66fc99e Initial load
duke
parents:
diff changeset
861 if (size == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // An unparsable object found. Signal early termination.
a61af66fc99e Initial load
duke
parents:
diff changeset
863 return addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
865 }
a61af66fc99e Initial load
duke
parents:
diff changeset
866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
867 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
869
a61af66fc99e Initial load
duke
parents:
diff changeset
870 // Callers of this iterator beware: The closure application should
a61af66fc99e Initial load
duke
parents:
diff changeset
871 // be robust in the face of uninitialized objects and should (always)
a61af66fc99e Initial load
duke
parents:
diff changeset
872 // return a correct size so that the next addr + size below gives us a
a61af66fc99e Initial load
duke
parents:
diff changeset
873 // valid block boundary. [See for instance,
a61af66fc99e Initial load
duke
parents:
diff changeset
874 // ScanMarkedObjectsAgainCarefullyClosure::do_object_careful()
a61af66fc99e Initial load
duke
parents:
diff changeset
875 // in ConcurrentMarkSweepGeneration.cpp.]
a61af66fc99e Initial load
duke
parents:
diff changeset
876 HeapWord*
a61af66fc99e Initial load
duke
parents:
diff changeset
877 CompactibleFreeListSpace::object_iterate_careful_m(MemRegion mr,
a61af66fc99e Initial load
duke
parents:
diff changeset
878 ObjectClosureCareful* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
879 assert_lock_strong(freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
880 // Can't use used_region() below because it may not necessarily
a61af66fc99e Initial load
duke
parents:
diff changeset
881 // be the same as [bottom(),end()); although we could
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // use [used_region().start(),round_to(used_region().end(),CardSize)),
a61af66fc99e Initial load
duke
parents:
diff changeset
883 // that appears too cumbersome, so we just do the simpler check
a61af66fc99e Initial load
duke
parents:
diff changeset
884 // in the assertion below.
a61af66fc99e Initial load
duke
parents:
diff changeset
885 assert(!mr.is_empty() && MemRegion(bottom(),end()).contains(mr),
a61af66fc99e Initial load
duke
parents:
diff changeset
886 "mr should be non-empty and within used space");
a61af66fc99e Initial load
duke
parents:
diff changeset
887 HeapWord *addr, *end;
a61af66fc99e Initial load
duke
parents:
diff changeset
888 size_t size;
a61af66fc99e Initial load
duke
parents:
diff changeset
889 for (addr = block_start_careful(mr.start()), end = mr.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
890 addr < end; addr += size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
891 FreeChunk* fc = (FreeChunk*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
892 if (fc->isFree()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
893 // Since we hold the free list lock, which protects direct
a61af66fc99e Initial load
duke
parents:
diff changeset
894 // allocation in this generation by mutators, a free object
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // will remain free throughout this iteration code.
a61af66fc99e Initial load
duke
parents:
diff changeset
896 size = fc->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
897 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
898 // Note that the object need not necessarily be initialized,
a61af66fc99e Initial load
duke
parents:
diff changeset
899 // because (for instance) the free list lock does NOT protect
a61af66fc99e Initial load
duke
parents:
diff changeset
900 // object initialization. The closure application below must
a61af66fc99e Initial load
duke
parents:
diff changeset
901 // therefore be correct in the face of uninitialized objects.
a61af66fc99e Initial load
duke
parents:
diff changeset
902 size = cl->do_object_careful_m(oop(addr), mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
903 if (size == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
904 // An unparsable object found. Signal early termination.
a61af66fc99e Initial load
duke
parents:
diff changeset
905 return addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
906 }
a61af66fc99e Initial load
duke
parents:
diff changeset
907 }
a61af66fc99e Initial load
duke
parents:
diff changeset
908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
909 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
911
a61af66fc99e Initial load
duke
parents:
diff changeset
912
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
913 HeapWord* CompactibleFreeListSpace::block_start_const(const void* p) const {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
914 NOT_PRODUCT(verify_objects_initialized());
a61af66fc99e Initial load
duke
parents:
diff changeset
915 return _bt.block_start(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918 HeapWord* CompactibleFreeListSpace::block_start_careful(const void* p) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 return _bt.block_start_careful(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
921
a61af66fc99e Initial load
duke
parents:
diff changeset
922 size_t CompactibleFreeListSpace::block_size(const HeapWord* p) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
923 NOT_PRODUCT(verify_objects_initialized());
a61af66fc99e Initial load
duke
parents:
diff changeset
924 assert(MemRegion(bottom(), end()).contains(p), "p not in space");
a61af66fc99e Initial load
duke
parents:
diff changeset
925 // This must be volatile, or else there is a danger that the compiler
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // will compile the code below into a sometimes-infinite loop, by keeping
a61af66fc99e Initial load
duke
parents:
diff changeset
927 // the value read the first time in a register.
a61af66fc99e Initial load
duke
parents:
diff changeset
928 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // We must do this until we get a consistent view of the object.
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
930 if (FreeChunk::indicatesFreeChunk(p)) {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
931 volatile FreeChunk* fc = (volatile FreeChunk*)p;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
932 size_t res = fc->size();
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
933 // If the object is still a free chunk, return the size, else it
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
934 // has been allocated so try again.
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
935 if (FreeChunk::indicatesFreeChunk(p)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
936 assert(res != 0, "Block size should not be 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
937 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
938 }
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
939 } else {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
940 // must read from what 'p' points to in each loop.
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
941 klassOop k = ((volatile oopDesc*)p)->klass_or_null();
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
942 if (k != NULL) {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
943 assert(k->is_oop(true /* ignore mark word */), "Should really be klass oop.");
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
944 oop o = (oop)p;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
945 assert(o->is_parsable(), "Should be parsable");
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
946 assert(o->is_oop(true /* ignore mark word */), "Should be an oop.");
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
947 size_t res = o->size_given_klass(k->klass_part());
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
948 res = adjustObjectSize(res);
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
949 assert(res != 0, "Block size should not be 0");
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
950 return res;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
951 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
955
a61af66fc99e Initial load
duke
parents:
diff changeset
956 // A variant of the above that uses the Printezis bits for
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // unparsable but allocated objects. This avoids any possible
a61af66fc99e Initial load
duke
parents:
diff changeset
958 // stalls waiting for mutators to initialize objects, and is
a61af66fc99e Initial load
duke
parents:
diff changeset
959 // thus potentially faster than the variant above. However,
a61af66fc99e Initial load
duke
parents:
diff changeset
960 // this variant may return a zero size for a block that is
a61af66fc99e Initial load
duke
parents:
diff changeset
961 // under mutation and for which a consistent size cannot be
a61af66fc99e Initial load
duke
parents:
diff changeset
962 // inferred without stalling; see CMSCollector::block_size_if_printezis_bits().
a61af66fc99e Initial load
duke
parents:
diff changeset
963 size_t CompactibleFreeListSpace::block_size_no_stall(HeapWord* p,
a61af66fc99e Initial load
duke
parents:
diff changeset
964 const CMSCollector* c)
a61af66fc99e Initial load
duke
parents:
diff changeset
965 const {
a61af66fc99e Initial load
duke
parents:
diff changeset
966 assert(MemRegion(bottom(), end()).contains(p), "p not in space");
a61af66fc99e Initial load
duke
parents:
diff changeset
967 // This must be volatile, or else there is a danger that the compiler
a61af66fc99e Initial load
duke
parents:
diff changeset
968 // will compile the code below into a sometimes-infinite loop, by keeping
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // the value read the first time in a register.
a61af66fc99e Initial load
duke
parents:
diff changeset
970 DEBUG_ONLY(uint loops = 0;)
a61af66fc99e Initial load
duke
parents:
diff changeset
971 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
972 // We must do this until we get a consistent view of the object.
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
973 if (FreeChunk::indicatesFreeChunk(p)) {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
974 volatile FreeChunk* fc = (volatile FreeChunk*)p;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
975 size_t res = fc->size();
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
976 if (FreeChunk::indicatesFreeChunk(p)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
977 assert(res != 0, "Block size should not be 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
978 assert(loops == 0, "Should be 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
979 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
980 }
a61af66fc99e Initial load
duke
parents:
diff changeset
981 } else {
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
982 // must read from what 'p' points to in each loop.
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
983 klassOop k = ((volatile oopDesc*)p)->klass_or_null();
518
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
984 if (k != NULL &&
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
985 ((oopDesc*)p)->is_parsable() &&
0af8b0718fc9 6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents: 517
diff changeset
986 ((oopDesc*)p)->is_conc_safe()) {
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
987 assert(k->is_oop(), "Should really be klass oop.");
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
988 oop o = (oop)p;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
989 assert(o->is_oop(), "Should be an oop");
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
990 size_t res = o->size_given_klass(k->klass_part());
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
991 res = adjustObjectSize(res);
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
992 assert(res != 0, "Block size should not be 0");
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
993 return res;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
994 } else {
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
995 return c->block_size_if_printezis_bits(p);
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
996 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
998 assert(loops == 0, "Can loop at most once");
a61af66fc99e Initial load
duke
parents:
diff changeset
999 DEBUG_ONLY(loops++;)
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 size_t CompactibleFreeListSpace::block_size_nopar(const HeapWord* p) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 NOT_PRODUCT(verify_objects_initialized());
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 assert(MemRegion(bottom(), end()).contains(p), "p not in space");
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 FreeChunk* fc = (FreeChunk*)p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 if (fc->isFree()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 return fc->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 // Ignore mark word because this may be a recently promoted
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 // object whose mark word is used to chain together grey
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 // objects (the last one would have a null value).
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 assert(oop(p)->is_oop(true), "Should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 return adjustObjectSize(oop(p)->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1017
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 // This implementation assumes that the property of "being an object" is
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 // stable. But being a free chunk may not be (because of parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 // promotion.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 bool CompactibleFreeListSpace::block_is_obj(const HeapWord* p) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 FreeChunk* fc = (FreeChunk*)p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 assert(is_in_reserved(p), "Should be in space");
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 // When doing a mark-sweep-compact of the CMS generation, this
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 // assertion may fail because prepare_for_compaction() uses
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 // space that is garbage to maintain information on ranges of
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 // live objects so that these live ranges can be moved as a whole.
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 // Comment out this assertion until that problem can be solved
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 // (i.e., that the block start calculation may look at objects
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 // at address below "p" in finding the object that contains "p"
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 // and those objects (if garbage) may have been modified to hold
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 // live range information.
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 // assert(ParallelGCThreads > 0 || _bt.block_start(p) == p, "Should be a block boundary");
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
1034 if (FreeChunk::indicatesFreeChunk(p)) return false;
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
1035 klassOop k = oop(p)->klass_or_null();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 if (k != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 // Ignore mark word because it may have been used to
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 // chain together promoted objects (the last one
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 // would have a null value).
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 assert(oop(p)->is_oop(true), "Should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 return false; // Was not an object at the start of collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1046
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 // Check if the object is alive. This fact is checked either by consulting
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 // the main marking bitmap in the sweeping phase or, if it's a permanent
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // generation and we're not in the sweeping phase, by checking the
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 // perm_gen_verify_bit_map where we store the "deadness" information if
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 // we did not sweep the perm gen in the most recent previous GC cycle.
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 bool CompactibleFreeListSpace::obj_is_alive(const HeapWord* p) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 assert (block_is_obj(p), "The address should point to an object");
a61af66fc99e Initial load
duke
parents:
diff changeset
1054
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 // If we're sweeping, we use object liveness information from the main bit map
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 // for both perm gen and old gen.
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 // We don't need to lock the bitmap (live_map or dead_map below), because
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 // EITHER we are in the middle of the sweeping phase, and the
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 // main marking bit map (live_map below) is locked,
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 // OR we're in other phases and perm_gen_verify_bit_map (dead_map below)
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 // is stable, because it's mutated only in the sweeping phase.
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 if (_collector->abstract_state() == CMSCollector::Sweeping) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 CMSBitMap* live_map = _collector->markBitMap();
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 return live_map->isMarked((HeapWord*) p);
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 // If we're not currently sweeping and we haven't swept the perm gen in
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 // the previous concurrent cycle then we may have dead but unswept objects
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 // in the perm gen. In this case, we use the "deadness" information
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 // that we had saved in perm_gen_verify_bit_map at the last sweep.
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 if (!CMSClassUnloadingEnabled && _collector->_permGen->reserved().contains(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 if (_collector->verifying()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 CMSBitMap* dead_map = _collector->perm_gen_verify_bit_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 // Object is marked in the dead_map bitmap at the previous sweep
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 // when we know that it's dead; if the bitmap is not allocated then
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 // the object is alive.
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 return (dead_map->sizeInBits() == 0) // bit_map has been allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 || !dead_map->par_isMarked((HeapWord*) p);
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 return false; // We can't say for sure if it's live, so we say that it's dead.
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1085
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 bool CompactibleFreeListSpace::block_is_obj_nopar(const HeapWord* p) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 FreeChunk* fc = (FreeChunk*)p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 assert(is_in_reserved(p), "Should be in space");
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 assert(_bt.block_start(p) == p, "Should be a block boundary");
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 if (!fc->isFree()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 // Ignore mark word because it may have been used to
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 // chain together promoted objects (the last one
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 // would have a null value).
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 assert(oop(p)->is_oop(true), "Should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1099
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 // "MT-safe but not guaranteed MT-precise" (TM); you may get an
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 // approximate answer if you don't hold the freelistlock when you call this.
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 size_t CompactibleFreeListSpace::totalSizeInIndexedFreeLists() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 size_t size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 debug_only(
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 // We may be calling here without the lock in which case we
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 // won't do this modest sanity check.
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 if (freelistLock()->owned_by_self()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 size_t total_list_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 fc = fc->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 total_list_size += i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 assert(total_list_size == i * _indexedFreeList[i].count(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 "Count in list is incorrect");
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 size += i * _indexedFreeList[i].count();
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1122
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 HeapWord* CompactibleFreeListSpace::par_allocate(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 return allocate(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1127
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 HeapWord*
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 CompactibleFreeListSpace::getChunkFromSmallLinearAllocBlockRemainder(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 return getChunkFromLinearAllocBlockRemainder(&_smallLinearAllocBlock, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1132
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 HeapWord* CompactibleFreeListSpace::allocate(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 assert_lock_strong(freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 HeapWord* res = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 assert(size == adjustObjectSize(size),
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 "use adjustObjectSize() before calling into allocate()");
a61af66fc99e Initial load
duke
parents:
diff changeset
1138
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 if (_adaptive_freelists) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 res = allocate_adaptive_freelists(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 } else { // non-adaptive free lists
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 res = allocate_non_adaptive_freelists(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1144
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 if (res != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 // check that res does lie in this space!
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 assert(is_in_reserved(res), "Not in this space!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 assert(is_aligned((void*)res), "alignment check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1149
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 FreeChunk* fc = (FreeChunk*)res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 fc->markNotFree();
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 assert(!fc->isFree(), "shouldn't be marked free");
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
1153 assert(oop(fc)->klass_or_null() == NULL, "should look uninitialized");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 // Verify that the block offset table shows this to
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 // be a single block, but not one which is unallocated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 _bt.verify_single_block(res, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 _bt.verify_not_unallocated(res, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 // mangle a just allocated object with a distinct pattern.
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 debug_only(fc->mangleAllocated(size));
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1161
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1164
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 HeapWord* CompactibleFreeListSpace::allocate_non_adaptive_freelists(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 HeapWord* res = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 // try and use linear allocation for smaller blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 if (size < _smallLinearAllocBlock._allocation_size_limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 // if successful, the following also adjusts block offset table
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 res = getChunkFromSmallLinearAllocBlock(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 // Else triage to indexed lists for smaller sizes
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 if (res == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 if (size < SmallForDictionary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 res = (HeapWord*) getChunkFromIndexedFreeList(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 // else get it from the big dictionary; if even this doesn't
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 // work we are out of luck.
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 res = (HeapWord*)getChunkFromDictionaryExact(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1182
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1185
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 HeapWord* CompactibleFreeListSpace::allocate_adaptive_freelists(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 assert_lock_strong(freelistLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 HeapWord* res = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 assert(size == adjustObjectSize(size),
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 "use adjustObjectSize() before calling into allocate()");
a61af66fc99e Initial load
duke
parents:
diff changeset
1191
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 // Strategy
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 // if small
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // exact size from small object indexed list if small
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 // small or large linear allocation block (linAB) as appropriate
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 // take from lists of greater sized chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // else
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 // dictionary
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 // small or large linear allocation block if it has the space
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 // Try allocating exact size from indexTable first
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 if (size < IndexSetSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 res = (HeapWord*) getChunkFromIndexedFreeList(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 if(res != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 assert(res != (HeapWord*)_indexedFreeList[size].head(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 "Not removed from free list");
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 // no block offset table adjustment is necessary on blocks in
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 // the indexed lists.
a61af66fc99e Initial load
duke
parents:
diff changeset
1208
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 // Try allocating from the small LinAB
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 } else if (size < _smallLinearAllocBlock._allocation_size_limit &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 (res = getChunkFromSmallLinearAllocBlock(size)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 // if successful, the above also adjusts block offset table
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 // Note that this call will refill the LinAB to
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 // satisfy the request. This is different that
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 // evm.
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 // Don't record chunk off a LinAB? smallSplitBirth(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1217
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // Raid the exact free lists larger than size, even if they are not
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 // overpopulated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 res = (HeapWord*) getChunkFromGreater(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 // Big objects get allocated directly from the dictionary.
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 res = (HeapWord*) getChunkFromDictionaryExact(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 if (res == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 // Try hard not to fail since an allocation failure will likely
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 // trigger a synchronous GC. Try to get the space from the
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 // allocation blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 res = getChunkFromSmallLinearAllocBlockRemainder(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1233
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1236
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 // A worst-case estimate of the space required (in HeapWords) to expand the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // when promoting obj.
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 size_t CompactibleFreeListSpace::expansionSpaceRequired(size_t obj_size) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 // Depending on the object size, expansion may require refilling either a
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 // bigLAB or a smallLAB plus refilling a PromotionInfo object. MinChunkSize
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 // is added because the dictionary may over-allocate to avoid fragmentation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 size_t space = obj_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 if (!_adaptive_freelists) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 space = MAX2(space, _smallLinearAllocBlock._refillSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 space += _promoInfo.refillSize() + 2 * MinChunkSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 return space;
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1250
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 FreeChunk* CompactibleFreeListSpace::getChunkFromGreater(size_t numWords) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 FreeChunk* ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
1253
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 assert(numWords >= MinChunkSize, "Size is less than minimum");
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 assert(linearAllocationWouldFail() || bestFitFirst(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 "Should not be here");
a61af66fc99e Initial load
duke
parents:
diff changeset
1257
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 size_t i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 size_t currSize = numWords + MinChunkSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 assert(currSize % MinObjAlignment == 0, "currSize should be aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 for (i = currSize; i < IndexSetSize; i += IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 FreeList* fl = &_indexedFreeList[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 if (fl->head()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 ret = getFromListGreater(fl, numWords);
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 assert(ret == NULL || ret->isFree(), "Should be returning a free chunk");
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1269
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 currSize = MAX2((size_t)SmallForDictionary,
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 (size_t)(numWords + MinChunkSize));
a61af66fc99e Initial load
duke
parents:
diff changeset
1272
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 /* Try to get a chunk that satisfies request, while avoiding
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 fragmentation that can't be handled. */
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 ret = dictionary()->getChunk(currSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 if (ret != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 assert(ret->size() - numWords >= MinChunkSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 "Chunk is too small");
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 _bt.allocated((HeapWord*)ret, ret->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 /* Carve returned chunk. */
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 (void) splitChunkAndReturnRemainder(ret, numWords);
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 /* Label this as no longer a free chunk. */
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 assert(ret->isFree(), "This chunk should be free");
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 ret->linkPrev(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 assert(ret == NULL || ret->isFree(), "Should be returning a free chunk");
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1292
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 bool CompactibleFreeListSpace::verifyChunkInIndexedFreeLists(FreeChunk* fc)
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 assert(fc->size() < IndexSetSize, "Size of chunk is too large");
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 return _indexedFreeList[fc->size()].verifyChunkInFreeLists(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1298
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 bool CompactibleFreeListSpace::verifyChunkInFreeLists(FreeChunk* fc) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 if (fc->size() >= IndexSetSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 return dictionary()->verifyChunkInFreeLists(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 return verifyChunkInIndexedFreeLists(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1306
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 void CompactibleFreeListSpace::assert_locked() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 CMSLockVerifier::assert_locked(freelistLock(), parDictionaryAllocLock());
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 }
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1311
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1312 void CompactibleFreeListSpace::assert_locked(const Mutex* lock) const {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1313 CMSLockVerifier::assert_locked(lock);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1314 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1316
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 FreeChunk* CompactibleFreeListSpace::allocateScratch(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 // In the parallel case, the main thread holds the free list lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 // on behalf the parallel threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 FreeChunk* fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 // If GC is parallel, this might be called by several threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 // This should be rare enough that the locking overhead won't affect
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 // the sequential code.
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 MutexLockerEx x(parDictionaryAllocLock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 fc = getChunkFromDictionary(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 if (fc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 fc->dontCoalesce();
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 assert(fc->isFree(), "Should be free, but not coalescable");
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 // Verify that the block offset table shows this to
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 // be a single block, but not one which is unallocated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 _bt.verify_single_block((HeapWord*)fc, fc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 _bt.verify_not_unallocated((HeapWord*)fc, fc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 return fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1339
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
1340 oop CompactibleFreeListSpace::promote(oop obj, size_t obj_size) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 assert(obj_size == (size_t)obj->size(), "bad obj_size passed in");
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1343
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 // if we are tracking promotions, then first ensure space for
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 // promotion (including spooling space for saving header if necessary).
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 // then allocate and copy, then track promoted info if needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 // When tracking (see PromotionInfo::track()), the mark word may
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 // be displaced and in this case restoration of the mark word
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 // occurs in the (oop_since_save_marks_)iterate phase.
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 if (_promoInfo.tracking() && !_promoInfo.ensure_spooling_space()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 // Call the allocate(size_t, bool) form directly to avoid the
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 // additional call through the allocate(size_t) form. Having
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 // the compile inline the call is problematic because allocate(size_t)
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 // is a virtual method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 HeapWord* res = allocate(adjustObjectSize(obj_size));
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 if (res != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 Copy::aligned_disjoint_words((HeapWord*)obj, res, obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 // if we should be tracking promotions, do so.
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 if (_promoInfo.tracking()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 _promoInfo.track((PromotedObject*)res);
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 return oop(res);
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1367
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 HeapWord*
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 CompactibleFreeListSpace::getChunkFromSmallLinearAllocBlock(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 assert(size >= MinChunkSize, "minimum chunk size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 assert(size < _smallLinearAllocBlock._allocation_size_limit,
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 "maximum from smallLinearAllocBlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 return getChunkFromLinearAllocBlock(&_smallLinearAllocBlock, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1376
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 HeapWord*
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 CompactibleFreeListSpace::getChunkFromLinearAllocBlock(LinearAllocBlock *blk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 assert(size >= MinChunkSize, "too small");
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 HeapWord* res = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 // Try to do linear allocation from blk, making sure that
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 if (blk->_word_size == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 // We have probably been unable to fill this either in the prologue or
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 // when it was exhausted at the last linear allocation. Bail out until
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 // next time.
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 assert(blk->_ptr == NULL, "consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 assert(blk->_word_size != 0 && blk->_ptr != NULL, "consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 res = getChunkFromLinearAllocBlockRemainder(blk, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 if (res != NULL) return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1394
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 // about to exhaust this linear allocation block
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 if (blk->_word_size == size) { // exactly satisfied
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 res = blk->_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 _bt.allocated(res, blk->_word_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 } else if (size + MinChunkSize <= blk->_refillSize) {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1400 size_t sz = blk->_word_size;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 // Update _unallocated_block if the size is such that chunk would be
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 // returned to the indexed free list. All other chunks in the indexed
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 // free lists are allocated from the dictionary so that _unallocated_block
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 // has already been adjusted for them. Do it here so that the cost
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 // for all chunks added back to the indexed free lists.
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1406 if (sz < SmallForDictionary) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1407 _bt.allocated(blk->_ptr, sz);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 // Return the chunk that isn't big enough, and then refill below.
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1410 addChunkToFreeLists(blk->_ptr, sz);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1411 splitBirth(sz);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 // Don't keep statistics on adding back chunk from a LinAB.
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 // A refilled block would not satisfy the request.
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1417
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 blk->_ptr = NULL; blk->_word_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 refillLinearAllocBlock(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 assert(blk->_ptr == NULL || blk->_word_size >= size + MinChunkSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 "block was replenished");
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 if (res != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 splitBirth(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 repairLinearAllocBlock(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 } else if (blk->_ptr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 res = blk->_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 size_t blk_size = blk->_word_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 blk->_word_size -= size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 blk->_ptr += size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 splitBirth(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 repairLinearAllocBlock(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 // Update BOT last so that other (parallel) GC threads see a consistent
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 // view of the BOT and free blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 // Above must occur before BOT is updated below.
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 _bt.split_block(res, blk_size, size); // adjust block offset table
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1439
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 HeapWord* CompactibleFreeListSpace::getChunkFromLinearAllocBlockRemainder(
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 LinearAllocBlock* blk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 assert(size >= MinChunkSize, "too small");
a61af66fc99e Initial load
duke
parents:
diff changeset
1445
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 HeapWord* res = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 // This is the common case. Keep it simple.
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 if (blk->_word_size >= size + MinChunkSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 assert(blk->_ptr != NULL, "consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 res = blk->_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 // Note that the BOT is up-to-date for the linAB before allocation. It
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 // indicates the start of the linAB. The split_block() updates the
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 // BOT for the linAB after the allocation (indicates the start of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 // next chunk to be allocated).
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 size_t blk_size = blk->_word_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 blk->_word_size -= size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 blk->_ptr += size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 splitBirth(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 repairLinearAllocBlock(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 // Update BOT last so that other (parallel) GC threads see a consistent
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 // view of the BOT and free blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 // Above must occur before BOT is updated below.
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 _bt.split_block(res, blk_size, size); // adjust block offset table
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 _bt.allocated(res, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1468
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 FreeChunk*
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 CompactibleFreeListSpace::getChunkFromIndexedFreeList(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 assert(size < SmallForDictionary, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 FreeChunk* res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 res = _indexedFreeList[size].getChunkAtHead();
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 if (res == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 res = getChunkFromIndexedFreeListHelper(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 _bt.verify_not_unallocated((HeapWord*) res, size);
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1479 assert(res == NULL || res->size() == size, "Incorrect block size");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1482
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 FreeChunk*
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1484 CompactibleFreeListSpace::getChunkFromIndexedFreeListHelper(size_t size,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1485 bool replenish) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 FreeChunk* fc = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 if (size < SmallForDictionary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 assert(_indexedFreeList[size].head() == NULL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 _indexedFreeList[size].surplus() <= 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 "List for this size should be empty or under populated");
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 // Try best fit in exact lists before replenishing the list
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 if (!bestFitFirst() || (fc = bestFitSmall(size)) == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 // Replenish list.
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 // Things tried that failed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 // Tried allocating out of the two LinAB's first before
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 // replenishing lists.
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 // Tried small linAB of size 256 (size in indexed list)
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 // and replenishing indexed lists from the small linAB.
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 FreeChunk* newFc = NULL;
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1503 const size_t replenish_size = CMSIndexedFreeListReplenish * size;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 if (replenish_size < SmallForDictionary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 // Do not replenish from an underpopulated size.
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 if (_indexedFreeList[replenish_size].surplus() > 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 _indexedFreeList[replenish_size].head() != NULL) {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1508 newFc = _indexedFreeList[replenish_size].getChunkAtHead();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1509 } else if (bestFitFirst()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 newFc = bestFitSmall(replenish_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 }
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1513 if (newFc == NULL && replenish_size > size) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 assert(CMSIndexedFreeListReplenish > 1, "ctl pt invariant");
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1515 newFc = getChunkFromIndexedFreeListHelper(replenish_size, false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 }
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1517 // Note: The stats update re split-death of block obtained above
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1518 // will be recorded below precisely when we know we are going to
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1519 // be actually splitting it into more than one pieces below.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 if (newFc != NULL) {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1521 if (replenish || CMSReplenishIntermediate) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1522 // Replenish this list and return one block to caller.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1523 size_t i;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1524 FreeChunk *curFc, *nextFc;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1525 size_t num_blk = newFc->size() / size;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1526 assert(num_blk >= 1, "Smaller than requested?");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1527 assert(newFc->size() % size == 0, "Should be integral multiple of request");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1528 if (num_blk > 1) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1529 // we are sure we will be splitting the block just obtained
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1530 // into multiple pieces; record the split-death of the original
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1531 splitDeath(replenish_size);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1532 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1533 // carve up and link blocks 0, ..., num_blk - 2
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1534 // The last chunk is not added to the lists but is returned as the
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1535 // free chunk.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1536 for (curFc = newFc, nextFc = (FreeChunk*)((HeapWord*)curFc + size),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1537 i = 0;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1538 i < (num_blk - 1);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1539 curFc = nextFc, nextFc = (FreeChunk*)((HeapWord*)nextFc + size),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1540 i++) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1541 curFc->setSize(size);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1542 // Don't record this as a return in order to try and
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1543 // determine the "returns" from a GC.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1544 _bt.verify_not_unallocated((HeapWord*) fc, size);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1545 _indexedFreeList[size].returnChunkAtTail(curFc, false);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1546 _bt.mark_block((HeapWord*)curFc, size);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1547 splitBirth(size);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1548 // Don't record the initial population of the indexed list
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1549 // as a split birth.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1550 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1551
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1552 // check that the arithmetic was OK above
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1553 assert((HeapWord*)nextFc == (HeapWord*)newFc + num_blk*size,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1554 "inconsistency in carving newFc");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 curFc->setSize(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 _bt.mark_block((HeapWord*)curFc, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 splitBirth(size);
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1558 fc = curFc;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1559 } else {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1560 // Return entire block to caller
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1561 fc = newFc;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 // Get a free chunk from the free chunk dictionary to be returned to
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 // replenish the indexed free list.
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 fc = getChunkFromDictionaryExact(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 }
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1570 // assert(fc == NULL || fc->isFree(), "Should be returning a free chunk");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 return fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1573
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 FreeChunk*
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 CompactibleFreeListSpace::getChunkFromDictionary(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 FreeChunk* fc = _dictionary->getChunk(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 if (fc == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 _bt.allocated((HeapWord*)fc, fc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 if (fc->size() >= size + MinChunkSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 fc = splitChunkAndReturnRemainder(fc, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 assert(fc->size() >= size, "chunk too small");
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 assert(fc->size() < size + MinChunkSize, "chunk too big");
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 _bt.verify_single_block((HeapWord*)fc, fc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 return fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1590
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 FreeChunk*
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 CompactibleFreeListSpace::getChunkFromDictionaryExact(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 FreeChunk* fc = _dictionary->getChunk(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 if (fc == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 return fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 _bt.allocated((HeapWord*)fc, fc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 if (fc->size() == size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 _bt.verify_single_block((HeapWord*)fc, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 return fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 assert(fc->size() > size, "getChunk() guarantee");
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 if (fc->size() < size + MinChunkSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 // Return the chunk to the dictionary and go get a bigger one.
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 returnChunkToDictionary(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 fc = _dictionary->getChunk(size + MinChunkSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 if (fc == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 _bt.allocated((HeapWord*)fc, fc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 assert(fc->size() >= size + MinChunkSize, "tautology");
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 fc = splitChunkAndReturnRemainder(fc, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 assert(fc->size() == size, "chunk is wrong size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 _bt.verify_single_block((HeapWord*)fc, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 return fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1619
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 CompactibleFreeListSpace::returnChunkToDictionary(FreeChunk* chunk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1623
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 size_t size = chunk->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 _bt.verify_single_block((HeapWord*)chunk, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 // adjust _unallocated_block downward, as necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 _bt.freed((HeapWord*)chunk, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 _dictionary->returnChunk(chunk);
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1629 #ifndef PRODUCT
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1630 if (CMSCollector::abstract_state() != CMSCollector::Sweeping) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1631 TreeChunk::as_TreeChunk(chunk)->list()->verify_stats();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1632 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1633 #endif // PRODUCT
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1635
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 CompactibleFreeListSpace::returnChunkToFreeList(FreeChunk* fc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 size_t size = fc->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 _bt.verify_single_block((HeapWord*) fc, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 _bt.verify_not_unallocated((HeapWord*) fc, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 if (_adaptive_freelists) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 _indexedFreeList[size].returnChunkAtTail(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 _indexedFreeList[size].returnChunkAtHead(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 }
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1647 #ifndef PRODUCT
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1648 if (CMSCollector::abstract_state() != CMSCollector::Sweeping) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1649 _indexedFreeList[size].verify_stats();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1650 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
1651 #endif // PRODUCT
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1653
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 // Add chunk to end of last block -- if it's the largest
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 // block -- and update BOT and census data. We would
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 // of course have preferred to coalesce it with the
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 // last block, but it's currently less expensive to find the
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 // largest block than it is to find the last.
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 CompactibleFreeListSpace::addChunkToFreeListsAtEndRecordingStats(
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 HeapWord* chunk, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 // check that the chunk does lie in this space!
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 assert(chunk != NULL && is_in_reserved(chunk), "Not in this space!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 // One of the parallel gc task threads may be here
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 // whilst others are allocating.
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 Mutex* lock = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 if (ParallelGCThreads != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 lock = &_parDictionaryAllocLock;
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 FreeChunk* ec;
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 ec = dictionary()->findLargestDict(); // get largest block
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 if (ec != NULL && ec->end() == chunk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 // It's a coterminal block - we can coalesce.
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 size_t old_size = ec->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 coalDeath(old_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 removeChunkFromDictionary(ec);
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 size += old_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 ec = (FreeChunk*)chunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 ec->setSize(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 debug_only(ec->mangleFreed(size));
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 if (size < SmallForDictionary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 lock = _indexedFreeListParLocks[size];
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 addChunkAndRepairOffsetTable((HeapWord*)ec, size, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 // record the birth under the lock since the recording involves
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 // manipulation of the list on which the chunk lives and
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 // if the chunk is allocated and is the last on the list,
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 // the list can go away.
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 coalBirth(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1697
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 CompactibleFreeListSpace::addChunkToFreeLists(HeapWord* chunk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 // check that the chunk does lie in this space!
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 assert(chunk != NULL && is_in_reserved(chunk), "Not in this space!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 _bt.verify_single_block(chunk, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1705
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 FreeChunk* fc = (FreeChunk*) chunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 fc->setSize(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 debug_only(fc->mangleFreed(size));
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 if (size < SmallForDictionary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 returnChunkToFreeList(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 returnChunkToDictionary(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1715
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 CompactibleFreeListSpace::addChunkAndRepairOffsetTable(HeapWord* chunk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 size_t size, bool coalesced) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 assert(chunk != NULL, "null chunk");
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 if (coalesced) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 // repair BOT
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 _bt.single_block(chunk, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 addChunkToFreeLists(chunk, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1727
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 // We _must_ find the purported chunk on our free lists;
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 // we assert if we don't.
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 CompactibleFreeListSpace::removeFreeChunkFromFreeLists(FreeChunk* fc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 size_t size = fc->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 debug_only(verifyFreeLists());
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 if (size < SmallForDictionary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 removeChunkFromIndexedFreeList(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 removeChunkFromDictionary(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 _bt.verify_single_block((HeapWord*)fc, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 debug_only(verifyFreeLists());
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1743
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 CompactibleFreeListSpace::removeChunkFromDictionary(FreeChunk* fc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 size_t size = fc->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 assert(fc != NULL, "null chunk");
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 _bt.verify_single_block((HeapWord*)fc, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 _dictionary->removeChunk(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 // adjust _unallocated_block upward, as necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 _bt.allocated((HeapWord*)fc, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1754
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 CompactibleFreeListSpace::removeChunkFromIndexedFreeList(FreeChunk* fc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 size_t size = fc->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 _bt.verify_single_block((HeapWord*)fc, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 if (FLSVerifyIndexTable) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 verifyIndexedFreeList(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 _indexedFreeList[size].removeChunk(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 debug_only(fc->clearNext());
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 debug_only(fc->clearPrev());
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 if (FLSVerifyIndexTable) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 verifyIndexedFreeList(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1774
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 FreeChunk* CompactibleFreeListSpace::bestFitSmall(size_t numWords) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 /* A hint is the next larger size that has a surplus.
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 Start search at a size large enough to guarantee that
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 the excess is >= MIN_CHUNK. */
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 size_t start = align_object_size(numWords + MinChunkSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 if (start < IndexSetSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 FreeList* it = _indexedFreeList;
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 size_t hint = _indexedFreeList[start].hint();
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 while (hint < IndexSetSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 assert(hint % MinObjAlignment == 0, "hint should be aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 FreeList *fl = &_indexedFreeList[hint];
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 if (fl->surplus() > 0 && fl->head() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 // Found a list with surplus, reset original hint
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 // and split out a free chunk which is returned.
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 _indexedFreeList[start].set_hint(hint);
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 FreeChunk* res = getFromListGreater(fl, numWords);
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 assert(res == NULL || res->isFree(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 "Should be returning a free chunk");
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 hint = fl->hint(); /* keep looking */
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 /* None found. */
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 it[start].set_hint(IndexSetSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1802
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 /* Requires fl->size >= numWords + MinChunkSize */
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList* fl,
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 size_t numWords) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 FreeChunk *curr = fl->head();
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 size_t oldNumWords = curr->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 assert(numWords >= MinChunkSize, "Word size is too small");
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 assert(curr != NULL, "List is empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 assert(oldNumWords >= numWords + MinChunkSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 "Size of chunks in the list is too small");
a61af66fc99e Initial load
duke
parents:
diff changeset
1812
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 fl->removeChunk(curr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 // recorded indirectly by splitChunkAndReturnRemainder -
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 // smallSplit(oldNumWords, numWords);
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 FreeChunk* new_chunk = splitChunkAndReturnRemainder(curr, numWords);
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 // Does anything have to be done for the remainder in terms of
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 // fixing the card table?
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 assert(new_chunk == NULL || new_chunk->isFree(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 "Should be returning a free chunk");
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 return new_chunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1823
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 FreeChunk*
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 CompactibleFreeListSpace::splitChunkAndReturnRemainder(FreeChunk* chunk,
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 size_t new_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 size_t size = chunk->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 assert(size > new_size, "Split from a smaller block?");
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 assert(is_aligned(chunk), "alignment problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 assert(size == adjustObjectSize(size), "alignment problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 size_t rem_size = size - new_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 assert(rem_size == adjustObjectSize(rem_size), "alignment problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 assert(rem_size >= MinChunkSize, "Free chunk smaller than minimum");
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 FreeChunk* ffc = (FreeChunk*)((HeapWord*)chunk + new_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 assert(is_aligned(ffc), "alignment problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 ffc->setSize(rem_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 ffc->linkNext(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 ffc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 // Above must occur before BOT is updated below.
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 // adjust block offset table
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 _bt.split_block((HeapWord*)chunk, chunk->size(), new_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 if (rem_size < SmallForDictionary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 bool is_par = (SharedHeap::heap()->n_par_threads() > 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 if (is_par) _indexedFreeListParLocks[rem_size]->lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 returnChunkToFreeList(ffc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 split(size, rem_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 if (is_par) _indexedFreeListParLocks[rem_size]->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 returnChunkToDictionary(ffc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 split(size ,rem_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 chunk->setSize(new_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 return chunk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1856
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 CompactibleFreeListSpace::sweep_completed() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 // Now that space is probably plentiful, refill linear
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 // allocation blocks as needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 refillLinearAllocBlocksIfNeeded();
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1863
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 CompactibleFreeListSpace::gc_prologue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 if (PrintFLSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 gclog_or_tty->print("Before GC:\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 reportFreeListStatistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 refillLinearAllocBlocksIfNeeded();
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1873
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 CompactibleFreeListSpace::gc_epilogue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 if (PrintGCDetails && Verbose && !_adaptive_freelists) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 if (_smallLinearAllocBlock._word_size == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 warning("CompactibleFreeListSpace(epilogue):: Linear allocation failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 assert(_promoInfo.noPromotions(), "_promoInfo inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 _promoInfo.stopTrackingPromotions();
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 repairLinearAllocationBlocks();
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 // Print Space's stats
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 if (PrintFLSStatistics != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 gclog_or_tty->print("After GC:\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 reportFreeListStatistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1890
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 // Iteration support, mostly delegated from a CMS generation
a61af66fc99e Initial load
duke
parents:
diff changeset
1892
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 void CompactibleFreeListSpace::save_marks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 // mark the "end" of the used space at the time of this call;
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 // note, however, that promoted objects from this point
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 // on are tracked in the _promoInfo below.
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 set_saved_mark_word(BlockOffsetArrayUseUnallocatedBlock ?
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 unallocated_block() : end());
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 // inform allocator that promotions should be tracked.
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 assert(_promoInfo.noPromotions(), "_promoInfo inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 _promoInfo.startTrackingPromotions();
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1903
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 bool CompactibleFreeListSpace::no_allocs_since_save_marks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 assert(_promoInfo.tracking(), "No preceding save_marks?");
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 guarantee(SharedHeap::heap()->n_par_threads() == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 "Shouldn't be called (yet) during parallel part of gc.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 return _promoInfo.noPromotions();
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1910
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 #define CFLS_OOP_SINCE_SAVE_MARKS_DEFN(OopClosureType, nv_suffix) \
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 \
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 void CompactibleFreeListSpace:: \
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 oop_since_save_marks_iterate##nv_suffix(OopClosureType* blk) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 assert(SharedHeap::heap()->n_par_threads() == 0, \
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 "Shouldn't be called (yet) during parallel part of gc."); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 _promoInfo.promoted_oops_iterate##nv_suffix(blk); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 /* \
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 * This also restores any displaced headers and removes the elements from \
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 * the iteration set as they are processed, so that we have a clean slate \
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 * at the end of the iteration. Note, thus, that if new objects are \
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 * promoted as a result of the iteration they are iterated over as well. \
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 */ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 assert(_promoInfo.noPromotions(), "_promoInfo inconsistency"); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1926
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 ALL_SINCE_SAVE_MARKS_CLOSURES(CFLS_OOP_SINCE_SAVE_MARKS_DEFN)
a61af66fc99e Initial load
duke
parents:
diff changeset
1928
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 //////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 // We go over the list of promoted objects, removing each from the list,
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 // and applying the closure (this may, in turn, add more elements to
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 // the tail of the promoted list, and these newly added objects will
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 // also be processed) until the list is empty.
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 // To aid verification and debugging, in the non-product builds
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 // we actually forward _promoHead each time we process a promoted oop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 // Note that this is not necessary in general (i.e. when we don't need to
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 // call PromotionInfo::verify()) because oop_iterate can only add to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 // end of _promoTail, and never needs to look at _promoHead.
a61af66fc99e Initial load
duke
parents:
diff changeset
1939
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 #define PROMOTED_OOPS_ITERATE_DEFN(OopClosureType, nv_suffix) \
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 \
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 void PromotionInfo::promoted_oops_iterate##nv_suffix(OopClosureType* cl) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 NOT_PRODUCT(verify()); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 PromotedObject *curObj, *nextObj; \
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 for (curObj = _promoHead; curObj != NULL; curObj = nextObj) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 if ((nextObj = curObj->next()) == NULL) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 /* protect ourselves against additions due to closure application \
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 below by resetting the list. */ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 assert(_promoTail == curObj, "Should have been the tail"); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 _promoHead = _promoTail = NULL; \
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 if (curObj->hasDisplacedMark()) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 /* restore displaced header */ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 oop(curObj)->set_mark(nextDisplacedHeader()); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 } else { \
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 /* restore prototypical header */ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 oop(curObj)->init_mark(); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 /* The "promoted_mark" should now not be set */ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 assert(!curObj->hasPromotedMark(), \
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 "Should have been cleared by restoring displaced mark-word"); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 NOT_PRODUCT(_promoHead = nextObj); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 if (cl != NULL) oop(curObj)->oop_iterate(cl); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 if (nextObj == NULL) { /* start at head of list reset above */ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 nextObj = _promoHead; \
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 assert(noPromotions(), "post-condition violation"); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 assert(_promoHead == NULL && _promoTail == NULL, "emptied promoted list");\
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 assert(_spoolHead == _spoolTail, "emptied spooling buffers"); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 assert(_firstIndex == _nextIndex, "empty buffer"); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1973
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 // This should have been ALL_SINCE_...() just like the others,
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 // but, because the body of the method above is somehwat longer,
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 // the MSVC compiler cannot cope; as a workaround, we split the
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 // macro into its 3 constituent parts below (see original macro
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 // definition in specializedOopClosures.hpp).
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG(PROMOTED_OOPS_ITERATE_DEFN)
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 PROMOTED_OOPS_ITERATE_DEFN(OopsInGenClosure,_v)
a61af66fc99e Initial load
duke
parents:
diff changeset
1981
a61af66fc99e Initial load
duke
parents:
diff changeset
1982
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 void CompactibleFreeListSpace::object_iterate_since_last_GC(ObjectClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 // ugghh... how would one do this efficiently for a non-contiguous space?
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 guarantee(false, "NYI");
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1987
12
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
1988 bool CompactibleFreeListSpace::linearAllocationWouldFail() const {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 return _smallLinearAllocBlock._word_size == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1991
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 void CompactibleFreeListSpace::repairLinearAllocationBlocks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 // Fix up linear allocation blocks to look like free blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 repairLinearAllocBlock(&_smallLinearAllocBlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1996
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 void CompactibleFreeListSpace::repairLinearAllocBlock(LinearAllocBlock* blk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 if (blk->_ptr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 assert(blk->_word_size != 0 && blk->_word_size >= MinChunkSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 "Minimum block size requirement");
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 FreeChunk* fc = (FreeChunk*)(blk->_ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 fc->setSize(blk->_word_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 fc->linkPrev(NULL); // mark as free
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 fc->dontCoalesce();
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 assert(fc->isFree(), "just marked it free");
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 assert(fc->cantCoalesce(), "just marked it uncoalescable");
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2010
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 void CompactibleFreeListSpace::refillLinearAllocBlocksIfNeeded() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 if (_smallLinearAllocBlock._ptr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 assert(_smallLinearAllocBlock._word_size == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 "Size of linAB should be zero if the ptr is NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 // Reset the linAB refill and allocation size limit.
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 _smallLinearAllocBlock.set(0, 0, 1024*SmallForLinearAlloc, SmallForLinearAlloc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 refillLinearAllocBlockIfNeeded(&_smallLinearAllocBlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2021
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 void
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 CompactibleFreeListSpace::refillLinearAllocBlockIfNeeded(LinearAllocBlock* blk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 assert((blk->_ptr == NULL && blk->_word_size == 0) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 (blk->_ptr != NULL && blk->_word_size >= MinChunkSize),
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 "blk invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 if (blk->_ptr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 refillLinearAllocBlock(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 if (blk->_word_size == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 warning("CompactibleFreeListSpace(prologue):: Linear allocation failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2037
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 void
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 CompactibleFreeListSpace::refillLinearAllocBlock(LinearAllocBlock* blk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 assert(blk->_word_size == 0 && blk->_ptr == NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 "linear allocation block should be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 FreeChunk* fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 if (blk->_refillSize < SmallForDictionary &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 (fc = getChunkFromIndexedFreeList(blk->_refillSize)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 // A linAB's strategy might be to use small sizes to reduce
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 // fragmentation but still get the benefits of allocation from a
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 // linAB.
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 fc = getChunkFromDictionary(blk->_refillSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 if (fc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 blk->_ptr = (HeapWord*)fc;
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 blk->_word_size = fc->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 fc->dontCoalesce(); // to prevent sweeper from sweeping us up
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2058
12
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2059 // Support for concurrent collection policy decisions.
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2060 bool CompactibleFreeListSpace::should_concurrent_collect() const {
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2061 // In the future we might want to add in frgamentation stats --
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2062 // including erosion of the "mountain" into this decision as well.
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2063 return !adaptive_freelists() && linearAllocationWouldFail();
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2064 }
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2065
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 // Support for compaction
a61af66fc99e Initial load
duke
parents:
diff changeset
2067
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 SCAN_AND_FORWARD(cp,end,block_is_obj,block_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 // prepare_for_compaction() uses the space between live objects
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 // so that later phase can skip dead space quickly. So verification
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 // of the free lists doesn't work after.
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2074
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 #define obj_size(q) adjustObjectSize(oop(q)->size())
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 #define adjust_obj_size(s) adjustObjectSize(s)
a61af66fc99e Initial load
duke
parents:
diff changeset
2077
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 void CompactibleFreeListSpace::adjust_pointers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 // In other versions of adjust_pointers(), a bail out
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 // based on the amount of live data in the generation
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 // (i.e., if 0, bail out) may be used.
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 // Cannot test used() == 0 here because the free lists have already
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 // been mangled by the compaction.
a61af66fc99e Initial load
duke
parents:
diff changeset
2084
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 SCAN_AND_ADJUST_POINTERS(adjust_obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 // See note about verification in prepare_for_compaction().
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2088
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 void CompactibleFreeListSpace::compact() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 SCAN_AND_COMPACT(obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2092
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 // fragmentation_metric = 1 - [sum of (fbs**2) / (sum of fbs)**2]
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 // where fbs is free block sizes
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 double CompactibleFreeListSpace::flsFrag() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 size_t itabFree = totalSizeInIndexedFreeLists();
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 double frag = 0.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 size_t i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2099
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 double sz = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 frag += _indexedFreeList[i].count() * (sz * sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2104
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 double totFree = itabFree +
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 _dictionary->totalChunkSize(DEBUG_ONLY(freelistLock()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 if (totFree > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 frag = ((frag + _dictionary->sum_of_squared_block_sizes()) /
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 (totFree * totFree));
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 frag = (double)1.0 - frag;
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 assert(frag == 0.0, "Follows from totFree == 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 return frag;
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2116
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 void CompactibleFreeListSpace::beginSweepFLCensus(
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 float inter_sweep_current,
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2119 float inter_sweep_estimate,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2120 float intra_sweep_estimate) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 size_t i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 FreeList* fl = &_indexedFreeList[i];
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2125 if (PrintFLSStatistics > 1) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2126 gclog_or_tty->print("size[%d] : ", i);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2127 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2128 fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2129 fl->set_coalDesired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 fl->set_beforeSweep(fl->count());
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 fl->set_bfrSurp(fl->surplus());
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 }
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2133 _dictionary->beginSweepDictCensus(CMSLargeCoalSurplusPercent,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 inter_sweep_current,
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2135 inter_sweep_estimate,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2136 intra_sweep_estimate);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2138
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 void CompactibleFreeListSpace::setFLSurplus() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 size_t i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 FreeList *fl = &_indexedFreeList[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 fl->set_surplus(fl->count() -
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2145 (ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2148
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 void CompactibleFreeListSpace::setFLHints() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 size_t i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 size_t h = IndexSetSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 for (i = IndexSetSize - 1; i != 0; i -= IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 FreeList *fl = &_indexedFreeList[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 fl->set_hint(h);
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 if (fl->surplus() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 h = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2161
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 void CompactibleFreeListSpace::clearFLCensus() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 FreeList *fl = &_indexedFreeList[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 fl->set_prevSweep(fl->count());
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 fl->set_coalBirths(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 fl->set_coalDeaths(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 fl->set_splitBirths(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 fl->set_splitDeaths(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2174
12
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2175 void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2176 if (PrintFLSStatistics > 0) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2177 HeapWord* largestAddr = (HeapWord*) dictionary()->findLargestDict();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2178 gclog_or_tty->print_cr("CMS: Large block " PTR_FORMAT,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2179 largestAddr);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2180 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 setFLSurplus();
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 setFLHints();
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 if (PrintGC && PrintFLSCensus > 0) {
12
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2184 printFLCensus(sweep_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 clearFLCensus();
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 assert_locked();
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2188 _dictionary->endSweepDictCensus(CMSLargeSplitSurplusPercent);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2190
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 bool CompactibleFreeListSpace::coalOverPopulated(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 if (size < SmallForDictionary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 FreeList *fl = &_indexedFreeList[size];
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 return (fl->coalDesired() < 0) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 ((int)fl->count() > fl->coalDesired());
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 return dictionary()->coalDictOverPopulated(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2200
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 void CompactibleFreeListSpace::smallCoalBirth(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 assert(size < SmallForDictionary, "Size too large for indexed list");
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 FreeList *fl = &_indexedFreeList[size];
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 fl->increment_coalBirths();
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 fl->increment_surplus();
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2207
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 void CompactibleFreeListSpace::smallCoalDeath(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 assert(size < SmallForDictionary, "Size too large for indexed list");
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 FreeList *fl = &_indexedFreeList[size];
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 fl->increment_coalDeaths();
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 fl->decrement_surplus();
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2214
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 void CompactibleFreeListSpace::coalBirth(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 if (size < SmallForDictionary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 smallCoalBirth(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 dictionary()->dictCensusUpdate(size,
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 false /* split */,
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 true /* birth */);
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2224
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 void CompactibleFreeListSpace::coalDeath(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 if(size < SmallForDictionary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 smallCoalDeath(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 dictionary()->dictCensusUpdate(size,
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 false /* split */,
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 false /* birth */);
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2234
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 void CompactibleFreeListSpace::smallSplitBirth(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 assert(size < SmallForDictionary, "Size too large for indexed list");
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 FreeList *fl = &_indexedFreeList[size];
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 fl->increment_splitBirths();
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 fl->increment_surplus();
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2241
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 void CompactibleFreeListSpace::smallSplitDeath(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 assert(size < SmallForDictionary, "Size too large for indexed list");
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 FreeList *fl = &_indexedFreeList[size];
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 fl->increment_splitDeaths();
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 fl->decrement_surplus();
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2248
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 void CompactibleFreeListSpace::splitBirth(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 if (size < SmallForDictionary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 smallSplitBirth(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 dictionary()->dictCensusUpdate(size,
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 true /* split */,
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 true /* birth */);
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2258
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 void CompactibleFreeListSpace::splitDeath(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 if (size < SmallForDictionary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 smallSplitDeath(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 dictionary()->dictCensusUpdate(size,
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 true /* split */,
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 false /* birth */);
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2268
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 void CompactibleFreeListSpace::split(size_t from, size_t to1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 size_t to2 = from - to1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 splitDeath(from);
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 splitBirth(to1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 splitBirth(to2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2275
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 void CompactibleFreeListSpace::print() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 tty->print(" CompactibleFreeListSpace");
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 Space::print();
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2280
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 void CompactibleFreeListSpace::prepare_for_verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 assert_locked();
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 repairLinearAllocationBlocks();
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 // Verify that the SpoolBlocks look like free blocks of
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 // appropriate sizes... To be done ...
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2287
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 class VerifyAllBlksClosure: public BlkClosure {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2289 private:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 const CompactibleFreeListSpace* _sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 const MemRegion _span;
a61af66fc99e Initial load
duke
parents:
diff changeset
2292
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 VerifyAllBlksClosure(const CompactibleFreeListSpace* sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 MemRegion span) : _sp(sp), _span(span) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
2296
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2297 virtual size_t do_blk(HeapWord* addr) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 size_t res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 if (_sp->block_is_obj(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 oop p = oop(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 guarantee(p->is_oop(), "Should be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 res = _sp->adjustObjectSize(p->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 if (_sp->obj_is_alive(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 p->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 FreeChunk* fc = (FreeChunk*)addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 res = fc->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 if (FLSVerifyLists && !fc->cantCoalesce()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 guarantee(_sp->verifyChunkInFreeLists(fc),
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 "Chunk should be on a free list");
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 guarantee(res != 0, "Livelock: no rank reduction!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2318
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 class VerifyAllOopsClosure: public OopClosure {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2320 private:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 const CMSCollector* _collector;
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 const CompactibleFreeListSpace* _sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 const MemRegion _span;
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 const bool _past_remark;
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 const CMSBitMap* _bit_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2326
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2327 protected:
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2328 void do_oop(void* p, oop obj) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2329 if (_span.contains(obj)) { // the interior oop points into CMS heap
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2330 if (!_span.contains(p)) { // reference from outside CMS heap
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2331 // Should be a valid object; the first disjunct below allows
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2332 // us to sidestep an assertion in block_is_obj() that insists
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2333 // that p be in _sp. Note that several generations (and spaces)
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2334 // are spanned by _span (CMS heap) above.
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2335 guarantee(!_sp->is_in_reserved(obj) ||
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2336 _sp->block_is_obj((HeapWord*)obj),
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2337 "Should be an object");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2338 guarantee(obj->is_oop(), "Should be an oop");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2339 obj->verify();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2340 if (_past_remark) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2341 // Remark has been completed, the object should be marked
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2342 _bit_map->isMarked((HeapWord*)obj);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2343 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2344 } else { // reference within CMS heap
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2345 if (_past_remark) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2346 // Remark has been completed -- so the referent should have
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2347 // been marked, if referring object is.
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2348 if (_bit_map->isMarked(_collector->block_start(p))) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2349 guarantee(_bit_map->isMarked((HeapWord*)obj), "Marking error?");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2350 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2351 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2352 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2353 } else if (_sp->is_in_reserved(p)) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2354 // the reference is from FLS, and points out of FLS
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2355 guarantee(obj->is_oop(), "Should be an oop");
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2356 obj->verify();
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2357 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2358 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2359
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2360 template <class T> void do_oop_work(T* p) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2361 T heap_oop = oopDesc::load_heap_oop(p);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2362 if (!oopDesc::is_null(heap_oop)) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2363 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2364 do_oop(p, obj);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2365 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2366 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2367
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 VerifyAllOopsClosure(const CMSCollector* collector,
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 const CompactibleFreeListSpace* sp, MemRegion span,
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 bool past_remark, CMSBitMap* bit_map) :
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 OopClosure(), _collector(collector), _sp(sp), _span(span),
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 _past_remark(past_remark), _bit_map(bit_map) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
2374
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2375 virtual void do_oop(oop* p) { VerifyAllOopsClosure::do_oop_work(p); }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 12
diff changeset
2376 virtual void do_oop(narrowOop* p) { VerifyAllOopsClosure::do_oop_work(p); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2378
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 void CompactibleFreeListSpace::verify(bool ignored) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 assert_lock_strong(&_freelistLock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 verify_objects_initialized();
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 MemRegion span = _collector->_span;
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 bool past_remark = (_collector->abstract_state() ==
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 CMSCollector::Sweeping);
a61af66fc99e Initial load
duke
parents:
diff changeset
2385
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2388
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 // Check integrity of CFL data structures
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 _promoInfo.verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 _dictionary->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 if (FLSVerifyIndexTable) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 verifyIndexedFreeLists();
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 // Check integrity of all objects and free blocks in space
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 VerifyAllBlksClosure cl(this, span);
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 ((CompactibleFreeListSpace*)this)->blk_iterate(&cl); // cast off const
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 // Check that all references in the heap to FLS
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 // are to valid objects in FLS or that references in
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 // FLS are to valid objects elsewhere in the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 if (FLSVerifyAllHeapReferences)
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 VerifyAllOopsClosure cl(_collector, this, span, past_remark,
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 _collector->markBitMap());
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 CollectedHeap* ch = Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 ch->oop_iterate(&cl); // all oops in generations
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 ch->permanent_oop_iterate(&cl); // all oops in perm gen
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2411
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 if (VerifyObjectStartArray) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 // Verify the block offset table
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 _bt.verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2417
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 void CompactibleFreeListSpace::verifyFreeLists() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 if (FLSVerifyLists) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 _dictionary->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 verifyIndexedFreeLists();
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 if (FLSVerifyDictionary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 _dictionary->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 if (FLSVerifyIndexTable) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 verifyIndexedFreeLists();
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2433
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 void CompactibleFreeListSpace::verifyIndexedFreeLists() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 size_t i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 for (; i < MinChunkSize; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 guarantee(_indexedFreeList[i].head() == NULL, "should be NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 for (; i < IndexSetSize; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 verifyIndexedFreeList(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2443
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 void CompactibleFreeListSpace::verifyIndexedFreeList(size_t size) const {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2445 FreeChunk* fc = _indexedFreeList[size].head();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2446 FreeChunk* tail = _indexedFreeList[size].tail();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2447 size_t num = _indexedFreeList[size].count();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2448 size_t n = 0;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
2449 guarantee((size % 2 == 0) || fc == NULL, "Odd slots should be empty");
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2450 for (; fc != NULL; fc = fc->next(), n++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 guarantee(fc->size() == size, "Size inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 guarantee(fc->isFree(), "!free?");
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 guarantee(fc->next() == NULL || fc->next()->prev() == fc, "Broken list");
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2454 guarantee((fc->next() == NULL) == (fc == tail), "Incorrect tail");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 }
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2456 guarantee(n == num, "Incorrect count");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2458
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 void CompactibleFreeListSpace::checkFreeListConsistency() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 assert(_dictionary->minSize() <= IndexSetSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
2462 "Some sizes can't be allocated without recourse to"
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 " linear allocation buffers");
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 assert(MIN_TREE_CHUNK_SIZE*HeapWordSize == sizeof(TreeChunk),
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 "else MIN_TREE_CHUNK_SIZE is wrong");
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 assert((IndexSetStride == 2 && IndexSetStart == 2) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 (IndexSetStride == 1 && IndexSetStart == 1), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 assert((IndexSetStride != 2) || (MinChunkSize % 2 == 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 "Some for-loops may be incorrectly initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 assert((IndexSetStride != 2) || (IndexSetSize % 2 == 1),
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 "For-loops that iterate over IndexSet with stride 2 may be wrong");
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2474
12
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2475 void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 assert_lock_strong(&_freelistLock);
12
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2477 FreeList total;
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2478 gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count);
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2479 FreeList::print_labels_on(gclog_or_tty, "size");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 size_t totalFree = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 const FreeList *fl = &_indexedFreeList[i];
12
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2483 totalFree += fl->count() * fl->size();
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2484 if (i % (40*IndexSetStride) == 0) {
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2485 FreeList::print_labels_on(gclog_or_tty, "size");
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2486 }
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2487 fl->print_on(gclog_or_tty);
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2488 total.set_bfrSurp( total.bfrSurp() + fl->bfrSurp() );
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2489 total.set_surplus( total.surplus() + fl->surplus() );
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2490 total.set_desired( total.desired() + fl->desired() );
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2491 total.set_prevSweep( total.prevSweep() + fl->prevSweep() );
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2492 total.set_beforeSweep(total.beforeSweep() + fl->beforeSweep());
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2493 total.set_count( total.count() + fl->count() );
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2494 total.set_coalBirths( total.coalBirths() + fl->coalBirths() );
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2495 total.set_coalDeaths( total.coalDeaths() + fl->coalDeaths() );
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2496 total.set_splitBirths(total.splitBirths() + fl->splitBirths());
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2497 total.set_splitDeaths(total.splitDeaths() + fl->splitDeaths());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 }
12
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2499 total.print_on(gclog_or_tty, "TOTAL");
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2500 gclog_or_tty->print_cr("Total free in indexed lists "
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2501 SIZE_FORMAT " words", totalFree);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 gclog_or_tty->print("growth: %8.5f deficit: %8.5f\n",
12
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2503 (double)(total.splitBirths()+total.coalBirths()-total.splitDeaths()-total.coalDeaths())/
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2504 (total.prevSweep() != 0 ? (double)total.prevSweep() : 1.0),
6432c3bb6240 6668743: CMS: Consolidate block statistics reporting code
ysr
parents: 0
diff changeset
2505 (double)(total.desired() - total.count())/(total.desired() != 0 ? (double)total.desired() : 1.0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 _dictionary->printDictCensus();
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2508
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 // Return the next displaced header, incrementing the pointer and
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 // recycling spool area as necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 markOop PromotionInfo::nextDisplacedHeader() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 assert(_spoolHead != NULL, "promotionInfo inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 assert(_spoolHead != _spoolTail || _firstIndex < _nextIndex,
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 "Empty spool space: no displaced header can be fetched");
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 assert(_spoolHead->bufferSize > _firstIndex, "Off by one error at head?");
a61af66fc99e Initial load
duke
parents:
diff changeset
2516 markOop hdr = _spoolHead->displacedHdr[_firstIndex];
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 // Spool forward
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 if (++_firstIndex == _spoolHead->bufferSize) { // last location in this block
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 // forward to next block, recycling this block into spare spool buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 SpoolBlock* tmp = _spoolHead->nextSpoolBlock;
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 assert(_spoolHead != _spoolTail, "Spooling storage mix-up");
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 _spoolHead->nextSpoolBlock = _spareSpool;
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 _spareSpool = _spoolHead;
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 _spoolHead = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 _firstIndex = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 if (_spoolHead == NULL) { // all buffers fully consumed
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 assert(_spoolTail == NULL && _nextIndex == 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 "spool buffers processing inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 )
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 return hdr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2535
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 void PromotionInfo::track(PromotedObject* trackOop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 track(trackOop, oop(trackOop)->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2539
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 void PromotionInfo::track(PromotedObject* trackOop, klassOop klassOfOop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 // make a copy of header as it may need to be spooled
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 markOop mark = oop(trackOop)->mark();
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 trackOop->clearNext();
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 if (mark->must_be_preserved_for_cms_scavenge(klassOfOop)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 // save non-prototypical header, and mark oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 saveDisplacedHeader(mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 trackOop->setDisplacedMark();
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 // we'd like to assert something like the following:
a61af66fc99e Initial load
duke
parents:
diff changeset
2550 // assert(mark == markOopDesc::prototype(), "consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 // ... but the above won't work because the age bits have not (yet) been
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 // cleared. The remainder of the check would be identical to the
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 // condition checked in must_be_preserved() above, so we don't really
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 // have anything useful to check here!
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2556 if (_promoTail != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 assert(_promoHead != NULL, "List consistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 _promoTail->setNext(trackOop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2559 _promoTail = trackOop;
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 assert(_promoHead == NULL, "List consistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 _promoHead = _promoTail = trackOop;
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 // Mask as newly promoted, so we can skip over such objects
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 // when scanning dirty cards
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 assert(!trackOop->hasPromotedMark(), "Should not have been marked");
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 trackOop->setPromotedMark();
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2569
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 // Save the given displaced header, incrementing the pointer and
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 // obtaining more spool area as necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 void PromotionInfo::saveDisplacedHeader(markOop hdr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 assert(_spoolHead != NULL && _spoolTail != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 "promotionInfo inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
2575 assert(_spoolTail->bufferSize > _nextIndex, "Off by one error at tail?");
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 _spoolTail->displacedHdr[_nextIndex] = hdr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 // Spool forward
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 if (++_nextIndex == _spoolTail->bufferSize) { // last location in this block
a61af66fc99e Initial load
duke
parents:
diff changeset
2579 // get a new spooling block
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 assert(_spoolTail->nextSpoolBlock == NULL, "tail should terminate spool list");
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 _splice_point = _spoolTail; // save for splicing
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 _spoolTail->nextSpoolBlock = getSpoolBlock(); // might fail
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 _spoolTail = _spoolTail->nextSpoolBlock; // might become NULL ...
a61af66fc99e Initial load
duke
parents:
diff changeset
2584 // ... but will attempt filling before next promotion attempt
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 _nextIndex = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2588
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 // Ensure that spooling space exists. Return false if spooling space
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 // could not be obtained.
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 bool PromotionInfo::ensure_spooling_space_work() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 assert(!has_spooling_space(), "Only call when there is no spooling space");
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 // Try and obtain more spooling space
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 SpoolBlock* newSpool = getSpoolBlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 assert(newSpool == NULL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 (newSpool->bufferSize != 0 && newSpool->nextSpoolBlock == NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 "getSpoolBlock() sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 if (newSpool == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2599 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 _nextIndex = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 if (_spoolTail == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 _spoolTail = newSpool;
a61af66fc99e Initial load
duke
parents:
diff changeset
2604 if (_spoolHead == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 _spoolHead = newSpool;
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 _firstIndex = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 assert(_splice_point != NULL && _splice_point->nextSpoolBlock == NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 "Splice point invariant");
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 // Extra check that _splice_point is connected to list
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2612 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2613 SpoolBlock* blk = _spoolHead;
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 for (; blk->nextSpoolBlock != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2615 blk = blk->nextSpoolBlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 assert(blk != NULL && blk == _splice_point,
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 "Splice point incorrect");
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 _splice_point->nextSpoolBlock = newSpool;
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 assert(_spoolHead != NULL, "spool list consistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 _spoolTail->nextSpoolBlock = newSpool;
a61af66fc99e Initial load
duke
parents:
diff changeset
2625 _spoolTail = newSpool;
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2629
a61af66fc99e Initial load
duke
parents:
diff changeset
2630 // Get a free spool buffer from the free pool, getting a new block
a61af66fc99e Initial load
duke
parents:
diff changeset
2631 // from the heap if necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 SpoolBlock* PromotionInfo::getSpoolBlock() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 SpoolBlock* res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 if ((res = _spareSpool) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 _spareSpool = _spareSpool->nextSpoolBlock;
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 res->nextSpoolBlock = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 } else { // spare spool exhausted, get some from heap
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 res = (SpoolBlock*)(space()->allocateScratch(refillSize()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2639 if (res != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 res->init();
a61af66fc99e Initial load
duke
parents:
diff changeset
2641 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 assert(res == NULL || res->nextSpoolBlock == NULL, "postcondition");
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2646
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 void PromotionInfo::startTrackingPromotions() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 assert(_spoolHead == _spoolTail && _firstIndex == _nextIndex,
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 "spooling inconsistency?");
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 _firstIndex = _nextIndex = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 _tracking = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2653
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2654 #define CMSPrintPromoBlockInfo 1
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2655
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2656 void PromotionInfo::stopTrackingPromotions(uint worker_id) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 assert(_spoolHead == _spoolTail && _firstIndex == _nextIndex,
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 "spooling inconsistency?");
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 _firstIndex = _nextIndex = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 _tracking = false;
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2661 if (CMSPrintPromoBlockInfo > 1) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2662 print_statistics(worker_id);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2663 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2664 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2665
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2666 void PromotionInfo::print_statistics(uint worker_id) const {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2667 assert(_spoolHead == _spoolTail && _firstIndex == _nextIndex,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2668 "Else will undercount");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2669 assert(CMSPrintPromoBlockInfo > 0, "Else unnecessary call");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2670 // Count the number of blocks and slots in the free pool
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2671 size_t slots = 0;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2672 size_t blocks = 0;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2673 for (SpoolBlock* cur_spool = _spareSpool;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2674 cur_spool != NULL;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2675 cur_spool = cur_spool->nextSpoolBlock) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2676 // the first entry is just a self-pointer; indices 1 through
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2677 // bufferSize - 1 are occupied (thus, bufferSize - 1 slots).
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2678 guarantee((void*)cur_spool->displacedHdr == (void*)&cur_spool->displacedHdr,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2679 "first entry of displacedHdr should be self-referential");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2680 slots += cur_spool->bufferSize - 1;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2681 blocks++;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2682 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2683 if (_spoolHead != NULL) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2684 slots += _spoolHead->bufferSize - 1;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2685 blocks++;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2686 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2687 gclog_or_tty->print_cr(" [worker %d] promo_blocks = %d, promo_slots = %d ",
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2688 worker_id, blocks, slots);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2690
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 // When _spoolTail is not NULL, then the slot <_spoolTail, _nextIndex>
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 // points to the next slot available for filling.
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 // The set of slots holding displaced headers are then all those in the
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 // right-open interval denoted by:
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 // [ <_spoolHead, _firstIndex>, <_spoolTail, _nextIndex> )
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 // When _spoolTail is NULL, then the set of slots with displaced headers
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 // is all those starting at the slot <_spoolHead, _firstIndex> and
a61af66fc99e Initial load
duke
parents:
diff changeset
2700 // going up to the last slot of last block in the linked list.
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 // In this lartter case, _splice_point points to the tail block of
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 // this linked list of blocks holding displaced headers.
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 void PromotionInfo::verify() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 // Verify the following:
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 // 1. the number of displaced headers matches the number of promoted
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 // objects that have displaced headers
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 // 2. each promoted object lies in this space
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 debug_only(
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 PromotedObject* junk = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 assert(junk->next_addr() == (void*)(oop(junk)->mark_addr()),
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 "Offset of PromotedObject::_next is expected to align with "
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 " the OopDesc::_mark within OopDesc");
a61af66fc99e Initial load
duke
parents:
diff changeset
2713 )
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 // FIXME: guarantee????
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 guarantee(_spoolHead == NULL || _spoolTail != NULL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 _splice_point != NULL, "list consistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 guarantee(_promoHead == NULL || _promoTail != NULL, "list consistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 // count the number of objects with displaced headers
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 size_t numObjsWithDisplacedHdrs = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 for (PromotedObject* curObj = _promoHead; curObj != NULL; curObj = curObj->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 guarantee(space()->is_in_reserved((HeapWord*)curObj), "Containment");
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 // the last promoted object may fail the mark() != NULL test of is_oop().
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 guarantee(curObj->next() == NULL || oop(curObj)->is_oop(), "must be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
2724 if (curObj->hasDisplacedMark()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 numObjsWithDisplacedHdrs++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 // Count the number of displaced headers
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 size_t numDisplacedHdrs = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2730 for (SpoolBlock* curSpool = _spoolHead;
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 curSpool != _spoolTail && curSpool != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 curSpool = curSpool->nextSpoolBlock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 // the first entry is just a self-pointer; indices 1 through
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 // bufferSize - 1 are occupied (thus, bufferSize - 1 slots).
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 guarantee((void*)curSpool->displacedHdr == (void*)&curSpool->displacedHdr,
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 "first entry of displacedHdr should be self-referential");
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 numDisplacedHdrs += curSpool->bufferSize - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 guarantee((_spoolHead == _spoolTail) == (numDisplacedHdrs == 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 "internal consistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 guarantee(_spoolTail != NULL || _nextIndex == 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 "Inconsistency between _spoolTail and _nextIndex");
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 // We overcounted (_firstIndex-1) worth of slots in block
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 // _spoolHead and we undercounted (_nextIndex-1) worth of
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 // slots in block _spoolTail. We make an appropriate
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 // adjustment by subtracting the first and adding the
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 // second: - (_firstIndex - 1) + (_nextIndex - 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 numDisplacedHdrs += (_nextIndex - _firstIndex);
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 guarantee(numDisplacedHdrs == numObjsWithDisplacedHdrs, "Displaced hdr count");
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2751
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2752 void PromotionInfo::print_on(outputStream* st) const {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2753 SpoolBlock* curSpool = NULL;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2754 size_t i = 0;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2755 st->print_cr("start & end indices: [" SIZE_FORMAT ", " SIZE_FORMAT ")",
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2756 _firstIndex, _nextIndex);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2757 for (curSpool = _spoolHead; curSpool != _spoolTail && curSpool != NULL;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2758 curSpool = curSpool->nextSpoolBlock) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2759 curSpool->print_on(st);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2760 st->print_cr(" active ");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2761 i++;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2762 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2763 for (curSpool = _spoolTail; curSpool != NULL;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2764 curSpool = curSpool->nextSpoolBlock) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2765 curSpool->print_on(st);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2766 st->print_cr(" inactive ");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2767 i++;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2768 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2769 for (curSpool = _spareSpool; curSpool != NULL;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2770 curSpool = curSpool->nextSpoolBlock) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2771 curSpool->print_on(st);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2772 st->print_cr(" free ");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2773 i++;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2774 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2775 st->print_cr(SIZE_FORMAT " header spooling blocks", i);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2776 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2777
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2778 void SpoolBlock::print_on(outputStream* st) const {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2779 st->print("[" PTR_FORMAT "," PTR_FORMAT "), " SIZE_FORMAT " HeapWords -> " PTR_FORMAT,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2780 this, (HeapWord*)displacedHdr + bufferSize,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2781 bufferSize, nextSpoolBlock);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2782 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2783
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2784 ///////////////////////////////////////////////////////////////////////////
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2785 // CFLS_LAB
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2786 ///////////////////////////////////////////////////////////////////////////
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2787
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2788 #define VECTOR_257(x) \
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2789 /* 1 2 3 4 5 6 7 8 9 1x 11 12 13 14 15 16 17 18 19 2x 21 22 23 24 25 26 27 28 29 3x 31 32 */ \
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2790 { x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2791 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2792 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2793 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2794 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2795 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2796 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2797 x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2798 x }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2799
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2800 // Initialize with default setting of CMSParPromoteBlocksToClaim, _not_
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2801 // OldPLABSize, whose static default is different; if overridden at the
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2802 // command-line, this will get reinitialized via a call to
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2803 // modify_initialization() below.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2804 AdaptiveWeightedAverage CFLS_LAB::_blocks_to_claim[] =
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2805 VECTOR_257(AdaptiveWeightedAverage(OldPLABWeight, (float)CMSParPromoteBlocksToClaim));
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2806 size_t CFLS_LAB::_global_num_blocks[] = VECTOR_257(0);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2807 int CFLS_LAB::_global_num_workers[] = VECTOR_257(0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2808
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 CFLS_LAB::CFLS_LAB(CompactibleFreeListSpace* cfls) :
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 _cfls(cfls)
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2812 assert(CompactibleFreeListSpace::IndexSetSize == 257, "Modify VECTOR_257() macro above");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 for (size_t i = CompactibleFreeListSpace::IndexSetStart;
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 i < CompactibleFreeListSpace::IndexSetSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
2815 i += CompactibleFreeListSpace::IndexSetStride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 _indexedFreeList[i].set_size(i);
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2817 _num_blocks[i] = 0;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2818 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2819 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2820
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2821 static bool _CFLS_LAB_modified = false;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2822
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2823 void CFLS_LAB::modify_initialization(size_t n, unsigned wt) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2824 assert(!_CFLS_LAB_modified, "Call only once");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2825 _CFLS_LAB_modified = true;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2826 for (size_t i = CompactibleFreeListSpace::IndexSetStart;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2827 i < CompactibleFreeListSpace::IndexSetSize;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2828 i += CompactibleFreeListSpace::IndexSetStride) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2829 _blocks_to_claim[i].modify(n, wt, true /* force */);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2832
a61af66fc99e Initial load
duke
parents:
diff changeset
2833 HeapWord* CFLS_LAB::alloc(size_t word_sz) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 FreeChunk* res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 word_sz = _cfls->adjustObjectSize(word_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 if (word_sz >= CompactibleFreeListSpace::IndexSetSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 // This locking manages sync with other large object allocations.
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 MutexLockerEx x(_cfls->parDictionaryAllocLock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 res = _cfls->getChunkFromDictionaryExact(word_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 if (res == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 FreeList* fl = &_indexedFreeList[word_sz];
a61af66fc99e Initial load
duke
parents:
diff changeset
2844 if (fl->count() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2845 // Attempt to refill this local free list.
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2846 get_from_global_pool(word_sz, fl);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 // If it didn't work, give up.
a61af66fc99e Initial load
duke
parents:
diff changeset
2848 if (fl->count() == 0) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2850 res = fl->getChunkAtHead();
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 assert(res != NULL, "Why was count non-zero?");
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 res->markNotFree();
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 assert(!res->isFree(), "shouldn't be marked free");
187
790e66e5fbac 6687581: Make CMS work with compressed oops
coleenp
parents: 113
diff changeset
2855 assert(oop(res)->klass_or_null() == NULL, "should look uninitialized");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2856 // mangle a just allocated object with a distinct pattern.
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 debug_only(res->mangleAllocated(word_sz));
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 return (HeapWord*)res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2860
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2861 // Get a chunk of blocks of the right size and update related
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2862 // book-keeping stats
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2863 void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList* fl) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2864 // Get the #blocks we want to claim
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2865 size_t n_blks = (size_t)_blocks_to_claim[word_sz].average();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2866 assert(n_blks > 0, "Error");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2867 assert(ResizePLAB || n_blks == OldPLABSize, "Error");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2868 // In some cases, when the application has a phase change,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2869 // there may be a sudden and sharp shift in the object survival
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2870 // profile, and updating the counts at the end of a scavenge
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2871 // may not be quick enough, giving rise to large scavenge pauses
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2872 // during these phase changes. It is beneficial to detect such
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2873 // changes on-the-fly during a scavenge and avoid such a phase-change
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2874 // pothole. The following code is a heuristic attempt to do that.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2875 // It is protected by a product flag until we have gained
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2876 // enough experience with this heuristic and fine-tuned its behaviour.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2877 // WARNING: This might increase fragmentation if we overreact to
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2878 // small spikes, so some kind of historical smoothing based on
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2879 // previous experience with the greater reactivity might be useful.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2880 // Lacking sufficient experience, CMSOldPLABResizeQuicker is disabled by
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2881 // default.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2882 if (ResizeOldPLAB && CMSOldPLABResizeQuicker) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2883 size_t multiple = _num_blocks[word_sz]/(CMSOldPLABToleranceFactor*CMSOldPLABNumRefills*n_blks);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2884 n_blks += CMSOldPLABReactivityFactor*multiple*n_blks;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2885 n_blks = MIN2(n_blks, CMSOldPLABMax);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2886 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2887 assert(n_blks > 0, "Error");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2888 _cfls->par_get_chunk_of_blocks(word_sz, n_blks, fl);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2889 // Update stats table entry for this block size
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2890 _num_blocks[word_sz] += fl->count();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2891 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2892
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2893 void CFLS_LAB::compute_desired_plab_size() {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2894 for (size_t i = CompactibleFreeListSpace::IndexSetStart;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 i < CompactibleFreeListSpace::IndexSetSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 i += CompactibleFreeListSpace::IndexSetStride) {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2897 assert((_global_num_workers[i] == 0) == (_global_num_blocks[i] == 0),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2898 "Counter inconsistency");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2899 if (_global_num_workers[i] > 0) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2900 // Need to smooth wrt historical average
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2901 if (ResizeOldPLAB) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2902 _blocks_to_claim[i].sample(
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2903 MAX2((size_t)CMSOldPLABMin,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2904 MIN2((size_t)CMSOldPLABMax,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2905 _global_num_blocks[i]/(_global_num_workers[i]*CMSOldPLABNumRefills))));
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2906 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2907 // Reset counters for next round
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2908 _global_num_workers[i] = 0;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2909 _global_num_blocks[i] = 0;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2910 if (PrintOldPLAB) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2911 gclog_or_tty->print_cr("[%d]: %d", i, (size_t)_blocks_to_claim[i].average());
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2912 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2916
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2917 void CFLS_LAB::retire(int tid) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2918 // We run this single threaded with the world stopped;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2919 // so no need for locks and such.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2920 #define CFLS_LAB_PARALLEL_ACCESS 0
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2921 NOT_PRODUCT(Thread* t = Thread::current();)
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2922 assert(Thread::current()->is_VM_thread(), "Error");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2923 assert(CompactibleFreeListSpace::IndexSetStart == CompactibleFreeListSpace::IndexSetStride,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2924 "Will access to uninitialized slot below");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2925 #if CFLS_LAB_PARALLEL_ACCESS
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2926 for (size_t i = CompactibleFreeListSpace::IndexSetSize - 1;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2927 i > 0;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2928 i -= CompactibleFreeListSpace::IndexSetStride) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2929 #else // CFLS_LAB_PARALLEL_ACCESS
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2930 for (size_t i = CompactibleFreeListSpace::IndexSetStart;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2931 i < CompactibleFreeListSpace::IndexSetSize;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2932 i += CompactibleFreeListSpace::IndexSetStride) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2933 #endif // !CFLS_LAB_PARALLEL_ACCESS
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2934 assert(_num_blocks[i] >= (size_t)_indexedFreeList[i].count(),
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2935 "Can't retire more than what we obtained");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2936 if (_num_blocks[i] > 0) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2937 size_t num_retire = _indexedFreeList[i].count();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2938 assert(_num_blocks[i] > num_retire, "Should have used at least one");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2939 {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2940 #if CFLS_LAB_PARALLEL_ACCESS
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2941 MutexLockerEx x(_cfls->_indexedFreeListParLocks[i],
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2942 Mutex::_no_safepoint_check_flag);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2943 #endif // CFLS_LAB_PARALLEL_ACCESS
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2944 // Update globals stats for num_blocks used
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2945 _global_num_blocks[i] += (_num_blocks[i] - num_retire);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2946 _global_num_workers[i]++;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2947 assert(_global_num_workers[i] <= (ssize_t)ParallelGCThreads, "Too big");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2948 if (num_retire > 0) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2949 _cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2950 // Reset this list.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2951 _indexedFreeList[i] = FreeList();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2952 _indexedFreeList[i].set_size(i);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2953 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2954 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2955 if (PrintOldPLAB) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2956 gclog_or_tty->print_cr("%d[%d]: %d/%d/%d",
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2957 tid, i, num_retire, _num_blocks[i], (size_t)_blocks_to_claim[i].average());
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2958 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2959 // Reset stats for next round
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2960 _num_blocks[i] = 0;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2961 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2962 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2963 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2964
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2965 void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 assert(fl->count() == 0, "Precondition.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2967 assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 "Precondition");
a61af66fc99e Initial load
duke
parents:
diff changeset
2969
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2970 // We'll try all multiples of word_sz in the indexed set, starting with
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2971 // word_sz itself and, if CMSSplitIndexedFreeListBlocks, try larger multiples,
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2972 // then try getting a big chunk and splitting it.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2973 {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2974 bool found;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2975 int k;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2976 size_t cur_sz;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2977 for (k = 1, cur_sz = k * word_sz, found = false;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2978 (cur_sz < CompactibleFreeListSpace::IndexSetSize) &&
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2979 (CMSSplitIndexedFreeListBlocks || k <= 1);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2980 k++, cur_sz = k * word_sz) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2981 FreeList* gfl = &_indexedFreeList[cur_sz];
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2982 FreeList fl_for_cur_sz; // Empty.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2983 fl_for_cur_sz.set_size(cur_sz);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2984 {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2985 MutexLockerEx x(_indexedFreeListParLocks[cur_sz],
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2986 Mutex::_no_safepoint_check_flag);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2987 if (gfl->count() != 0) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2988 // nn is the number of chunks of size cur_sz that
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2989 // we'd need to split k-ways each, in order to create
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2990 // "n" chunks of size word_sz each.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2991 const size_t nn = MAX2(n/k, (size_t)1);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2992 gfl->getFirstNChunksFromList(nn, &fl_for_cur_sz);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2993 found = true;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2994 if (k > 1) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2995 // Update split death stats for the cur_sz-size blocks list:
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2996 // we increment the split death count by the number of blocks
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2997 // we just took from the cur_sz-size blocks list and which
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2998 // we will be splitting below.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
2999 ssize_t deaths = _indexedFreeList[cur_sz].splitDeaths() +
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3000 fl_for_cur_sz.count();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3001 _indexedFreeList[cur_sz].set_splitDeaths(deaths);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3002 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3003 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3004 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3005 // Now transfer fl_for_cur_sz to fl. Common case, we hope, is k = 1.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3006 if (found) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3007 if (k == 1) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3008 fl->prepend(&fl_for_cur_sz);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3009 } else {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3010 // Divide each block on fl_for_cur_sz up k ways.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3011 FreeChunk* fc;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3012 while ((fc = fl_for_cur_sz.getChunkAtHead()) != NULL) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3013 // Must do this in reverse order, so that anybody attempting to
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3014 // access the main chunk sees it as a single free block until we
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3015 // change it.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3016 size_t fc_size = fc->size();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3017 for (int i = k-1; i >= 0; i--) {
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3018 FreeChunk* ffc = (FreeChunk*)((HeapWord*)fc + i * word_sz);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3019 ffc->setSize(word_sz);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3020 ffc->linkNext(NULL);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3021 ffc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3022 // Above must occur before BOT is updated below.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3023 // splitting from the right, fc_size == (k - i + 1) * wordsize
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3024 _bt.mark_block((HeapWord*)ffc, word_sz);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3025 fc_size -= word_sz;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3026 _bt.verify_not_unallocated((HeapWord*)ffc, ffc->size());
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3027 _bt.verify_single_block((HeapWord*)fc, fc_size);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3028 _bt.verify_single_block((HeapWord*)ffc, ffc->size());
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3029 // Push this on "fl".
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3030 fl->returnChunkAtHead(ffc);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3031 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3032 // TRAP
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3033 assert(fl->tail()->next() == NULL, "List invariant.");
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3034 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3035 }
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3036 // Update birth stats for this block size.
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3037 size_t num = fl->count();
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3038 MutexLockerEx x(_indexedFreeListParLocks[word_sz],
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3039 Mutex::_no_safepoint_check_flag);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3040 ssize_t births = _indexedFreeList[word_sz].splitBirths() + num;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3041 _indexedFreeList[word_sz].set_splitBirths(births);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3042 return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 // Otherwise, we'll split a block from the dictionary.
a61af66fc99e Initial load
duke
parents:
diff changeset
3047 FreeChunk* fc = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 FreeChunk* rem_fc = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 size_t rem;
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 MutexLockerEx x(parDictionaryAllocLock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 while (n > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3054 fc = dictionary()->getChunk(MAX2(n * word_sz,
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 _dictionary->minSize()),
a61af66fc99e Initial load
duke
parents:
diff changeset
3056 FreeBlockDictionary::atLeast);
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 if (fc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 _bt.allocated((HeapWord*)fc, fc->size()); // update _unallocated_blk
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 dictionary()->dictCensusUpdate(fc->size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 true /*split*/,
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 false /*birth*/);
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 n--;
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 if (fc == NULL) return;
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3068 assert((ssize_t)n >= 1, "Control point invariant");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3069 // Otherwise, split up that block.
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3070 const size_t nn = fc->size() / word_sz;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 n = MIN2(nn, n);
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3072 assert((ssize_t)n >= 1, "Control point invariant");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 rem = fc->size() - n * word_sz;
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 // If there is a remainder, and it's too small, allocate one fewer.
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 if (rem > 0 && rem < MinChunkSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 n--; rem += word_sz;
a61af66fc99e Initial load
duke
parents:
diff changeset
3077 }
1148
05b775309e59 6912018: CMS: guarantee(head() != 0,"The head of the list cannot be NULL")
jmasa
parents: 1145
diff changeset
3078 // Note that at this point we may have n == 0.
05b775309e59 6912018: CMS: guarantee(head() != 0,"The head of the list cannot be NULL")
jmasa
parents: 1145
diff changeset
3079 assert((ssize_t)n >= 0, "Control point invariant");
05b775309e59 6912018: CMS: guarantee(head() != 0,"The head of the list cannot be NULL")
jmasa
parents: 1145
diff changeset
3080
05b775309e59 6912018: CMS: guarantee(head() != 0,"The head of the list cannot be NULL")
jmasa
parents: 1145
diff changeset
3081 // If n is 0, the chunk fc that was found is not large
05b775309e59 6912018: CMS: guarantee(head() != 0,"The head of the list cannot be NULL")
jmasa
parents: 1145
diff changeset
3082 // enough to leave a viable remainder. We are unable to
05b775309e59 6912018: CMS: guarantee(head() != 0,"The head of the list cannot be NULL")
jmasa
parents: 1145
diff changeset
3083 // allocate even one block. Return fc to the
05b775309e59 6912018: CMS: guarantee(head() != 0,"The head of the list cannot be NULL")
jmasa
parents: 1145
diff changeset
3084 // dictionary and return, leaving "fl" empty.
05b775309e59 6912018: CMS: guarantee(head() != 0,"The head of the list cannot be NULL")
jmasa
parents: 1145
diff changeset
3085 if (n == 0) {
05b775309e59 6912018: CMS: guarantee(head() != 0,"The head of the list cannot be NULL")
jmasa
parents: 1145
diff changeset
3086 returnChunkToDictionary(fc);
05b775309e59 6912018: CMS: guarantee(head() != 0,"The head of the list cannot be NULL")
jmasa
parents: 1145
diff changeset
3087 return;
05b775309e59 6912018: CMS: guarantee(head() != 0,"The head of the list cannot be NULL")
jmasa
parents: 1145
diff changeset
3088 }
05b775309e59 6912018: CMS: guarantee(head() != 0,"The head of the list cannot be NULL")
jmasa
parents: 1145
diff changeset
3089
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 // First return the remainder, if any.
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 // Note that we hold the lock until we decide if we're going to give
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3092 // back the remainder to the dictionary, since a concurrent allocation
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 // may otherwise see the heap as empty. (We're willing to take that
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 // hit if the block is a small block.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 if (rem > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 size_t prefix_size = n * word_sz;
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 rem_fc = (FreeChunk*)((HeapWord*)fc + prefix_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 rem_fc->setSize(rem);
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 rem_fc->linkNext(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 rem_fc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 // Above must occur before BOT is updated below.
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3102 assert((ssize_t)n > 0 && prefix_size > 0 && rem_fc > fc, "Error");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 _bt.split_block((HeapWord*)fc, fc->size(), prefix_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 if (rem >= IndexSetSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 returnChunkToDictionary(rem_fc);
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3106 dictionary()->dictCensusUpdate(rem, true /*split*/, true /*birth*/);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 rem_fc = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3109 // Otherwise, return it to the small list below.
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3112 if (rem_fc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 MutexLockerEx x(_indexedFreeListParLocks[rem],
a61af66fc99e Initial load
duke
parents:
diff changeset
3114 Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3115 _bt.verify_not_unallocated((HeapWord*)rem_fc, rem_fc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 _indexedFreeList[rem].returnChunkAtHead(rem_fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 smallSplitBirth(rem);
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 }
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3119 assert((ssize_t)n > 0 && fc != NULL, "Consistency");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 // Now do the splitting up.
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 // Must do this in reverse order, so that anybody attempting to
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 // access the main chunk sees it as a single free block until we
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 // change it.
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 size_t fc_size = n * word_sz;
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 // All but first chunk in this loop
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 for (ssize_t i = n-1; i > 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3127 FreeChunk* ffc = (FreeChunk*)((HeapWord*)fc + i * word_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 ffc->setSize(word_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 ffc->linkNext(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 ffc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 // Above must occur before BOT is updated below.
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 // splitting from the right, fc_size == (n - i + 1) * wordsize
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 _bt.mark_block((HeapWord*)ffc, word_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 fc_size -= word_sz;
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 _bt.verify_not_unallocated((HeapWord*)ffc, ffc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3136 _bt.verify_single_block((HeapWord*)ffc, ffc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 _bt.verify_single_block((HeapWord*)fc, fc_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 // Push this on "fl".
a61af66fc99e Initial load
duke
parents:
diff changeset
3139 fl->returnChunkAtHead(ffc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3141 // First chunk
a61af66fc99e Initial load
duke
parents:
diff changeset
3142 fc->setSize(word_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 fc->linkNext(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 fc->linkPrev(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 _bt.verify_not_unallocated((HeapWord*)fc, fc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 _bt.verify_single_block((HeapWord*)fc, fc->size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 fl->returnChunkAtHead(fc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3148
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3149 assert((ssize_t)n > 0 && (ssize_t)n == fl->count(), "Incorrect number of blocks");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3150 {
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3151 // Update the stats for this block size.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3152 MutexLockerEx x(_indexedFreeListParLocks[word_sz],
a61af66fc99e Initial load
duke
parents:
diff changeset
3153 Mutex::_no_safepoint_check_flag);
1145
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3154 const ssize_t births = _indexedFreeList[word_sz].splitBirths() + n;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3155 _indexedFreeList[word_sz].set_splitBirths(births);
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3156 // ssize_t new_surplus = _indexedFreeList[word_sz].surplus() + n;
e018e6884bd8 6631166: CMS: better heuristics when combatting fragmentation
ysr
parents: 579
diff changeset
3157 // _indexedFreeList[word_sz].set_surplus(new_surplus);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3159
a61af66fc99e Initial load
duke
parents:
diff changeset
3160 // TRAP
a61af66fc99e Initial load
duke
parents:
diff changeset
3161 assert(fl->tail()->next() == NULL, "List invariant.");
a61af66fc99e Initial load
duke
parents:
diff changeset
3162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3163
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 // Set up the space's par_seq_tasks structure for work claiming
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 // for parallel rescan. See CMSParRemarkTask where this is currently used.
a61af66fc99e Initial load
duke
parents:
diff changeset
3166 // XXX Need to suitably abstract and generalize this and the next
a61af66fc99e Initial load
duke
parents:
diff changeset
3167 // method into one.
a61af66fc99e Initial load
duke
parents:
diff changeset
3168 void
a61af66fc99e Initial load
duke
parents:
diff changeset
3169 CompactibleFreeListSpace::
a61af66fc99e Initial load
duke
parents:
diff changeset
3170 initialize_sequential_subtasks_for_rescan(int n_threads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3171 // The "size" of each task is fixed according to rescan_task_size.
a61af66fc99e Initial load
duke
parents:
diff changeset
3172 assert(n_threads > 0, "Unexpected n_threads argument");
a61af66fc99e Initial load
duke
parents:
diff changeset
3173 const size_t task_size = rescan_task_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3174 size_t n_tasks = (used_region().word_size() + task_size - 1)/task_size;
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 269
diff changeset
3175 assert((n_tasks == 0) == used_region().is_empty(), "n_tasks incorrect");
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 269
diff changeset
3176 assert(n_tasks == 0 ||
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 269
diff changeset
3177 ((used_region().start() + (n_tasks - 1)*task_size < used_region().end()) &&
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 269
diff changeset
3178 (used_region().start() + n_tasks*task_size >= used_region().end())),
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 269
diff changeset
3179 "n_tasks calculation incorrect");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3180 SequentialSubTasksDone* pst = conc_par_seq_tasks();
a61af66fc99e Initial load
duke
parents:
diff changeset
3181 assert(!pst->valid(), "Clobbering existing data?");
a61af66fc99e Initial load
duke
parents:
diff changeset
3182 pst->set_par_threads(n_threads);
a61af66fc99e Initial load
duke
parents:
diff changeset
3183 pst->set_n_tasks((int)n_tasks);
a61af66fc99e Initial load
duke
parents:
diff changeset
3184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3185
a61af66fc99e Initial load
duke
parents:
diff changeset
3186 // Set up the space's par_seq_tasks structure for work claiming
a61af66fc99e Initial load
duke
parents:
diff changeset
3187 // for parallel concurrent marking. See CMSConcMarkTask where this is currently used.
a61af66fc99e Initial load
duke
parents:
diff changeset
3188 void
a61af66fc99e Initial load
duke
parents:
diff changeset
3189 CompactibleFreeListSpace::
a61af66fc99e Initial load
duke
parents:
diff changeset
3190 initialize_sequential_subtasks_for_marking(int n_threads,
a61af66fc99e Initial load
duke
parents:
diff changeset
3191 HeapWord* low) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3192 // The "size" of each task is fixed according to rescan_task_size.
a61af66fc99e Initial load
duke
parents:
diff changeset
3193 assert(n_threads > 0, "Unexpected n_threads argument");
a61af66fc99e Initial load
duke
parents:
diff changeset
3194 const size_t task_size = marking_task_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3195 assert(task_size > CardTableModRefBS::card_size_in_words &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3196 (task_size % CardTableModRefBS::card_size_in_words == 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
3197 "Otherwise arithmetic below would be incorrect");
a61af66fc99e Initial load
duke
parents:
diff changeset
3198 MemRegion span = _gen->reserved();
a61af66fc99e Initial load
duke
parents:
diff changeset
3199 if (low != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 if (span.contains(low)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3201 // Align low down to a card boundary so that
a61af66fc99e Initial load
duke
parents:
diff changeset
3202 // we can use block_offset_careful() on span boundaries.
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 HeapWord* aligned_low = (HeapWord*)align_size_down((uintptr_t)low,
a61af66fc99e Initial load
duke
parents:
diff changeset
3204 CardTableModRefBS::card_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3205 // Clip span prefix at aligned_low
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 span = span.intersection(MemRegion(aligned_low, span.end()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 } else if (low > span.end()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3208 span = MemRegion(low, low); // Null region
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 } // else use entire span
a61af66fc99e Initial load
duke
parents:
diff changeset
3210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3211 assert(span.is_empty() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3212 ((uintptr_t)span.start() % CardTableModRefBS::card_size == 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 "span should start at a card boundary");
a61af66fc99e Initial load
duke
parents:
diff changeset
3214 size_t n_tasks = (span.word_size() + task_size - 1)/task_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3215 assert((n_tasks == 0) == span.is_empty(), "Inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
3216 assert(n_tasks == 0 ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3217 ((span.start() + (n_tasks - 1)*task_size < span.end()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3218 (span.start() + n_tasks*task_size >= span.end())),
340
ebeb6490b814 6722116: CMS: Incorrect overflow handling when using parallel concurrent marking
ysr
parents: 269
diff changeset
3219 "n_tasks calculation incorrect");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3220 SequentialSubTasksDone* pst = conc_par_seq_tasks();
a61af66fc99e Initial load
duke
parents:
diff changeset
3221 assert(!pst->valid(), "Clobbering existing data?");
a61af66fc99e Initial load
duke
parents:
diff changeset
3222 pst->set_par_threads(n_threads);
a61af66fc99e Initial load
duke
parents:
diff changeset
3223 pst->set_n_tasks((int)n_tasks);
a61af66fc99e Initial load
duke
parents:
diff changeset
3224 }