annotate src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @ 1571:2d127394260e

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