annotate src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @ 1972:f95d63e2154a

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