annotate src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp @ 1091:6aa7255741f3

6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
author ysr
date Thu, 03 Dec 2009 15:01:57 -0800
parents 0fbdb4381b99
children c18cbe5936b8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
579
0fbdb4381b99 6814575: Update copyright year
xdono
parents: 481
diff changeset
2 * Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_psMarkSweepDecorator.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 PSMarkSweepDecorator* PSMarkSweepDecorator::_destination_decorator = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
29
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 void PSMarkSweepDecorator::set_destination_decorator_tenured() {
a61af66fc99e Initial load
duke
parents:
diff changeset
32 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
33 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 _destination_decorator = heap->old_gen()->object_mark_sweep();
a61af66fc99e Initial load
duke
parents:
diff changeset
36 }
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 void PSMarkSweepDecorator::set_destination_decorator_perm_gen() {
a61af66fc99e Initial load
duke
parents:
diff changeset
39 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
40 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
41
a61af66fc99e Initial load
duke
parents:
diff changeset
42 _destination_decorator = heap->perm_gen()->object_mark_sweep();
a61af66fc99e Initial load
duke
parents:
diff changeset
43 }
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 void PSMarkSweepDecorator::advance_destination_decorator() {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
47 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 assert(_destination_decorator != NULL, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
50 guarantee(_destination_decorator != heap->perm_gen()->object_mark_sweep(), "Cannot advance perm gen decorator");
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 PSMarkSweepDecorator* first = heap->old_gen()->object_mark_sweep();
a61af66fc99e Initial load
duke
parents:
diff changeset
53 PSMarkSweepDecorator* second = heap->young_gen()->eden_mark_sweep();
a61af66fc99e Initial load
duke
parents:
diff changeset
54 PSMarkSweepDecorator* third = heap->young_gen()->from_mark_sweep();
a61af66fc99e Initial load
duke
parents:
diff changeset
55 PSMarkSweepDecorator* fourth = heap->young_gen()->to_mark_sweep();
a61af66fc99e Initial load
duke
parents:
diff changeset
56
a61af66fc99e Initial load
duke
parents:
diff changeset
57 if ( _destination_decorator == first ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
58 _destination_decorator = second;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 } else if ( _destination_decorator == second ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 _destination_decorator = third;
a61af66fc99e Initial load
duke
parents:
diff changeset
61 } else if ( _destination_decorator == third ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
62 _destination_decorator = fourth;
a61af66fc99e Initial load
duke
parents:
diff changeset
63 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 fatal("PSMarkSweep attempting to advance past last compaction area");
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
a61af66fc99e Initial load
duke
parents:
diff changeset
66 }
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 PSMarkSweepDecorator* PSMarkSweepDecorator::destination_decorator() {
a61af66fc99e Initial load
duke
parents:
diff changeset
69 assert(_destination_decorator != NULL, "Sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 return _destination_decorator;
a61af66fc99e Initial load
duke
parents:
diff changeset
72 }
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // FIX ME FIX ME FIX ME FIX ME!!!!!!!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // The object forwarding code is duplicated. Factor this out!!!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
76 //
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // This method "precompacts" objects inside its space to dest. It places forwarding
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // pointers into markOops for use by adjust_pointers. If "dest" should overflow, we
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // finish by compacting into our own space.
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 void PSMarkSweepDecorator::precompact() {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // Reset our own compact top.
a61af66fc99e Initial load
duke
parents:
diff changeset
83 set_compaction_top(space()->bottom());
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 /* We allow some amount of garbage towards the bottom of the space, so
a61af66fc99e Initial load
duke
parents:
diff changeset
86 * we don't start compacting before there is a significant gain to be made.
a61af66fc99e Initial load
duke
parents:
diff changeset
87 * Occasionally, we want to ensure a full compaction, which is determined
a61af66fc99e Initial load
duke
parents:
diff changeset
88 * by the MarkSweepAlwaysCompactCount parameter. This is a significant
a61af66fc99e Initial load
duke
parents:
diff changeset
89 * performance improvement!
a61af66fc99e Initial load
duke
parents:
diff changeset
90 */
a61af66fc99e Initial load
duke
parents:
diff changeset
91 bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
92
438
122d10c82f3f 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 374
diff changeset
93 size_t allowed_deadspace = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
94 if (skip_dead) {
438
122d10c82f3f 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 374
diff changeset
95 const size_t ratio = allowed_dead_ratio();
122d10c82f3f 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 374
diff changeset
96 allowed_deadspace = space()->capacity_in_words() * ratio / 100;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
97 }
a61af66fc99e Initial load
duke
parents:
diff changeset
98
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // Fetch the current destination decorator
a61af66fc99e Initial load
duke
parents:
diff changeset
100 PSMarkSweepDecorator* dest = destination_decorator();
a61af66fc99e Initial load
duke
parents:
diff changeset
101 ObjectStartArray* start_array = dest->start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
102
a61af66fc99e Initial load
duke
parents:
diff changeset
103 HeapWord* compact_top = dest->compaction_top();
a61af66fc99e Initial load
duke
parents:
diff changeset
104 HeapWord* compact_end = dest->space()->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 HeapWord* q = space()->bottom();
a61af66fc99e Initial load
duke
parents:
diff changeset
107 HeapWord* t = space()->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 HeapWord* end_of_live= q; /* One byte beyond the last byte of the last
a61af66fc99e Initial load
duke
parents:
diff changeset
110 live object. */
a61af66fc99e Initial load
duke
parents:
diff changeset
111 HeapWord* first_dead = space()->end(); /* The first dead object. */
a61af66fc99e Initial load
duke
parents:
diff changeset
112 LiveRange* liveRange = NULL; /* The current live range, recorded in the
a61af66fc99e Initial load
duke
parents:
diff changeset
113 first header of preceding free area. */
a61af66fc99e Initial load
duke
parents:
diff changeset
114 _first_dead = first_dead;
a61af66fc99e Initial load
duke
parents:
diff changeset
115
a61af66fc99e Initial load
duke
parents:
diff changeset
116 const intx interval = PrefetchScanIntervalInBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
117
a61af66fc99e Initial load
duke
parents:
diff changeset
118 while (q < t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
119 assert(oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
120 oop(q)->mark()->has_bias_pattern(),
a61af66fc99e Initial load
duke
parents:
diff changeset
121 "these are the only valid states during a mark sweep");
a61af66fc99e Initial load
duke
parents:
diff changeset
122 if (oop(q)->is_gc_marked()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
123 /* prefetch beyond q */
a61af66fc99e Initial load
duke
parents:
diff changeset
124 Prefetch::write(q, interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
125 size_t size = oop(q)->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
126
a61af66fc99e Initial load
duke
parents:
diff changeset
127 size_t compaction_max_size = pointer_delta(compact_end, compact_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // This should only happen if a space in the young gen overflows the
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // old gen. If that should happen, we null out the start_array, because
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // the young spaces are not covered by one.
a61af66fc99e Initial load
duke
parents:
diff changeset
132 while(size > compaction_max_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // First record the last compact_top
a61af66fc99e Initial load
duke
parents:
diff changeset
134 dest->set_compaction_top(compact_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // Advance to the next compaction decorator
a61af66fc99e Initial load
duke
parents:
diff changeset
137 advance_destination_decorator();
a61af66fc99e Initial load
duke
parents:
diff changeset
138 dest = destination_decorator();
a61af66fc99e Initial load
duke
parents:
diff changeset
139
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // Update compaction info
a61af66fc99e Initial load
duke
parents:
diff changeset
141 start_array = dest->start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
142 compact_top = dest->compaction_top();
a61af66fc99e Initial load
duke
parents:
diff changeset
143 compact_end = dest->space()->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
144 assert(compact_top == dest->space()->bottom(), "Advanced to space already in use");
a61af66fc99e Initial load
duke
parents:
diff changeset
145 assert(compact_end > compact_top, "Must always be space remaining");
a61af66fc99e Initial load
duke
parents:
diff changeset
146 compaction_max_size =
a61af66fc99e Initial load
duke
parents:
diff changeset
147 pointer_delta(compact_end, compact_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // store the forwarding pointer into the mark word
a61af66fc99e Initial load
duke
parents:
diff changeset
151 if (q != compact_top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
152 oop(q)->forward_to(oop(compact_top));
a61af66fc99e Initial load
duke
parents:
diff changeset
153 assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
a61af66fc99e Initial load
duke
parents:
diff changeset
154 } else {
374
a4b729f5b611 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 269
diff changeset
155 // if the object isn't moving we can just set the mark to the default
a4b729f5b611 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 269
diff changeset
156 // mark and handle it specially later on.
a4b729f5b611 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 269
diff changeset
157 oop(q)->init_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
158 assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // Update object start array
374
a4b729f5b611 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 269
diff changeset
162 if (start_array) {
a4b729f5b611 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 269
diff changeset
163 start_array->allocate_block(compact_top);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
165
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
166 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), size));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
167 compact_top += size;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 assert(compact_top <= dest->space()->end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
169 "Exceeding space in destination");
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 q += size;
a61af66fc99e Initial load
duke
parents:
diff changeset
172 end_of_live = q;
a61af66fc99e Initial load
duke
parents:
diff changeset
173 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 /* run over all the contiguous dead objects */
a61af66fc99e Initial load
duke
parents:
diff changeset
175 HeapWord* end = q;
a61af66fc99e Initial load
duke
parents:
diff changeset
176 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 /* prefetch beyond end */
a61af66fc99e Initial load
duke
parents:
diff changeset
178 Prefetch::write(end, interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 end += oop(end)->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
180 } while (end < t && (!oop(end)->is_gc_marked()));
a61af66fc99e Initial load
duke
parents:
diff changeset
181
a61af66fc99e Initial load
duke
parents:
diff changeset
182 /* see if we might want to pretend this object is alive so that
a61af66fc99e Initial load
duke
parents:
diff changeset
183 * we don't have to compact quite as often.
a61af66fc99e Initial load
duke
parents:
diff changeset
184 */
a61af66fc99e Initial load
duke
parents:
diff changeset
185 if (allowed_deadspace > 0 && q == compact_top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
186 size_t sz = pointer_delta(end, q);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 if (insert_deadspace(allowed_deadspace, q, sz)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
188 size_t compaction_max_size = pointer_delta(compact_end, compact_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // This should only happen if a space in the young gen overflows the
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // old gen. If that should happen, we null out the start_array, because
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // the young spaces are not covered by one.
a61af66fc99e Initial load
duke
parents:
diff changeset
193 while (sz > compaction_max_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // First record the last compact_top
a61af66fc99e Initial load
duke
parents:
diff changeset
195 dest->set_compaction_top(compact_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // Advance to the next compaction decorator
a61af66fc99e Initial load
duke
parents:
diff changeset
198 advance_destination_decorator();
a61af66fc99e Initial load
duke
parents:
diff changeset
199 dest = destination_decorator();
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // Update compaction info
a61af66fc99e Initial load
duke
parents:
diff changeset
202 start_array = dest->start_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
203 compact_top = dest->compaction_top();
a61af66fc99e Initial load
duke
parents:
diff changeset
204 compact_end = dest->space()->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
205 assert(compact_top == dest->space()->bottom(), "Advanced to space already in use");
a61af66fc99e Initial load
duke
parents:
diff changeset
206 assert(compact_end > compact_top, "Must always be space remaining");
a61af66fc99e Initial load
duke
parents:
diff changeset
207 compaction_max_size =
a61af66fc99e Initial load
duke
parents:
diff changeset
208 pointer_delta(compact_end, compact_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // store the forwarding pointer into the mark word
a61af66fc99e Initial load
duke
parents:
diff changeset
212 if (q != compact_top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 oop(q)->forward_to(oop(compact_top));
a61af66fc99e Initial load
duke
parents:
diff changeset
214 assert(oop(q)->is_gc_marked(), "encoding the pointer should preserve the mark");
a61af66fc99e Initial load
duke
parents:
diff changeset
215 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // if the object isn't moving we can just set the mark to the default
374
a4b729f5b611 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 269
diff changeset
217 // mark and handle it specially later on.
a4b729f5b611 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 269
diff changeset
218 oop(q)->init_mark();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
219 assert(oop(q)->forwardee() == NULL, "should be forwarded to NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221
374
a4b729f5b611 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 269
diff changeset
222 // Update object start array
a4b729f5b611 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 269
diff changeset
223 if (start_array) {
a4b729f5b611 6716466: par compact - remove VerifyParallelOldWithMarkSweep code
jcoomes
parents: 269
diff changeset
224 start_array->allocate_block(compact_top);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
226
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
227 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), sz));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
228 compact_top += sz;
a61af66fc99e Initial load
duke
parents:
diff changeset
229 assert(compact_top <= dest->space()->end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
230 "Exceeding space in destination");
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 q = end;
a61af66fc99e Initial load
duke
parents:
diff changeset
233 end_of_live = end;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
237
a61af66fc99e Initial load
duke
parents:
diff changeset
238 /* for the previous LiveRange, record the end of the live objects. */
a61af66fc99e Initial load
duke
parents:
diff changeset
239 if (liveRange) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 liveRange->set_end(q);
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 /* record the current LiveRange object.
a61af66fc99e Initial load
duke
parents:
diff changeset
244 * liveRange->start() is overlaid on the mark word.
a61af66fc99e Initial load
duke
parents:
diff changeset
245 */
a61af66fc99e Initial load
duke
parents:
diff changeset
246 liveRange = (LiveRange*)q;
a61af66fc99e Initial load
duke
parents:
diff changeset
247 liveRange->set_start(end);
a61af66fc99e Initial load
duke
parents:
diff changeset
248 liveRange->set_end(end);
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 /* see if this is the first dead region. */
a61af66fc99e Initial load
duke
parents:
diff changeset
251 if (q < first_dead) {
a61af66fc99e Initial load
duke
parents:
diff changeset
252 first_dead = q;
a61af66fc99e Initial load
duke
parents:
diff changeset
253 }
a61af66fc99e Initial load
duke
parents:
diff changeset
254
a61af66fc99e Initial load
duke
parents:
diff changeset
255 /* move on to the next object */
a61af66fc99e Initial load
duke
parents:
diff changeset
256 q = end;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 assert(q == t, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
261 if (liveRange != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 liveRange->set_end(q);
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264 _end_of_live = end_of_live;
a61af66fc99e Initial load
duke
parents:
diff changeset
265 if (end_of_live < first_dead) {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 first_dead = end_of_live;
a61af66fc99e Initial load
duke
parents:
diff changeset
267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
268 _first_dead = first_dead;
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // Update compaction top
a61af66fc99e Initial load
duke
parents:
diff changeset
271 dest->set_compaction_top(compact_top);
a61af66fc99e Initial load
duke
parents:
diff changeset
272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
273
438
122d10c82f3f 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 374
diff changeset
274 bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
122d10c82f3f 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 374
diff changeset
275 HeapWord* q, size_t deadlength) {
122d10c82f3f 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 374
diff changeset
276 if (allowed_deadspace_words >= deadlength) {
122d10c82f3f 6765804: GC "dead ratios" should be unsigned
jcoomes
parents: 374
diff changeset
277 allowed_deadspace_words -= deadlength;
481
7d7a7c599c17 6578152: fill_region_with_object has usability and safety issues
jcoomes
parents: 438
diff changeset
278 CollectedHeap::fill_with_object(q, deadlength);
7d7a7c599c17 6578152: fill_region_with_object has usability and safety issues
jcoomes
parents: 438
diff changeset
279 oop(q)->set_mark(oop(q)->mark()->set_marked());
7d7a7c599c17 6578152: fill_region_with_object has usability and safety issues
jcoomes
parents: 438
diff changeset
280 assert((int) deadlength == oop(q)->size(), "bad filler object size");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // Recall that we required "q == compaction_top".
a61af66fc99e Initial load
duke
parents:
diff changeset
282 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
283 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
284 allowed_deadspace_words = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
285 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
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 PSMarkSweepDecorator::adjust_pointers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // adjust all the interior pointers to point at the new locations of objects
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // Used by MarkSweep::mark_sweep_phase3()
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 HeapWord* q = space()->bottom();
a61af66fc99e Initial load
duke
parents:
diff changeset
294 HeapWord* t = _end_of_live; // Established by "prepare_for_compaction".
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296 assert(_first_dead <= _end_of_live, "Stands to reason, no?");
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 if (q < t && _first_dead > q &&
a61af66fc99e Initial load
duke
parents:
diff changeset
299 !oop(q)->is_gc_marked()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // we have a chunk of the space which hasn't moved and we've
a61af66fc99e Initial load
duke
parents:
diff changeset
301 // reinitialized the mark word during the previous pass, so we can't
a61af66fc99e Initial load
duke
parents:
diff changeset
302 // use is_gc_marked for the traversal.
a61af66fc99e Initial load
duke
parents:
diff changeset
303 HeapWord* end = _first_dead;
a61af66fc99e Initial load
duke
parents:
diff changeset
304
a61af66fc99e Initial load
duke
parents:
diff changeset
305 while (q < end) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
306 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
307 // point all the oops to the new location
a61af66fc99e Initial load
duke
parents:
diff changeset
308 size_t size = oop(q)->adjust_pointers();
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
309 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers());
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
310 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
311 q += size;
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 if (_first_dead == t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 q = t;
a61af66fc99e Initial load
duke
parents:
diff changeset
316 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 // $$$ This is funky. Using this to read the previously written
a61af66fc99e Initial load
duke
parents:
diff changeset
318 // LiveRange. See also use below.
a61af66fc99e Initial load
duke
parents:
diff changeset
319 q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322 const intx interval = PrefetchScanIntervalInBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324 debug_only(HeapWord* prev_q = NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
325 while (q < t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // prefetch beyond q
a61af66fc99e Initial load
duke
parents:
diff changeset
327 Prefetch::write(q, interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
328 if (oop(q)->is_gc_marked()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // q is alive
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
330 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // point all the oops to the new location
a61af66fc99e Initial load
duke
parents:
diff changeset
332 size_t size = oop(q)->adjust_pointers();
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
333 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers());
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
334 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
335 debug_only(prev_q = q);
a61af66fc99e Initial load
duke
parents:
diff changeset
336 q += size;
a61af66fc99e Initial load
duke
parents:
diff changeset
337 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // q is not a live object, so its mark should point at the next
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // live object
a61af66fc99e Initial load
duke
parents:
diff changeset
340 debug_only(prev_q = q);
a61af66fc99e Initial load
duke
parents:
diff changeset
341 q = (HeapWord*) oop(q)->mark()->decode_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
342 assert(q > prev_q, "we should be moving forward through memory");
a61af66fc99e Initial load
duke
parents:
diff changeset
343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 assert(q == t, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 void PSMarkSweepDecorator::compact(bool mangle_free_space ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // Copy all live objects to their new location
a61af66fc99e Initial load
duke
parents:
diff changeset
351 // Used by MarkSweep::mark_sweep_phase4()
a61af66fc99e Initial load
duke
parents:
diff changeset
352
a61af66fc99e Initial load
duke
parents:
diff changeset
353 HeapWord* q = space()->bottom();
a61af66fc99e Initial load
duke
parents:
diff changeset
354 HeapWord* const t = _end_of_live;
a61af66fc99e Initial load
duke
parents:
diff changeset
355 debug_only(HeapWord* prev_q = NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
356
a61af66fc99e Initial load
duke
parents:
diff changeset
357 if (q < t && _first_dead > q &&
a61af66fc99e Initial load
duke
parents:
diff changeset
358 !oop(q)->is_gc_marked()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
359 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // we have a chunk of the space which hasn't moved and we've reinitialized the
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // mark word during the previous pass, so we can't use is_gc_marked for the
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // traversal.
a61af66fc99e Initial load
duke
parents:
diff changeset
363 HeapWord* const end = _first_dead;
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 while (q < end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 size_t size = oop(q)->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
367 assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
368 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, q));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
369 debug_only(prev_q = q);
a61af66fc99e Initial load
duke
parents:
diff changeset
370 q += size;
a61af66fc99e Initial load
duke
parents:
diff changeset
371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
372 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
373
a61af66fc99e Initial load
duke
parents:
diff changeset
374 if (_first_dead == t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
375 q = t;
a61af66fc99e Initial load
duke
parents:
diff changeset
376 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // $$$ Funky
a61af66fc99e Initial load
duke
parents:
diff changeset
378 q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
380 }
a61af66fc99e Initial load
duke
parents:
diff changeset
381
a61af66fc99e Initial load
duke
parents:
diff changeset
382 const intx scan_interval = PrefetchScanIntervalInBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
383 const intx copy_interval = PrefetchCopyIntervalInBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
384
a61af66fc99e Initial load
duke
parents:
diff changeset
385 while (q < t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
386 if (!oop(q)->is_gc_marked()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // mark is pointer to next marked oop
a61af66fc99e Initial load
duke
parents:
diff changeset
388 debug_only(prev_q = q);
a61af66fc99e Initial load
duke
parents:
diff changeset
389 q = (HeapWord*) oop(q)->mark()->decode_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
390 assert(q > prev_q, "we should be moving forward through memory");
a61af66fc99e Initial load
duke
parents:
diff changeset
391 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // prefetch beyond q
a61af66fc99e Initial load
duke
parents:
diff changeset
393 Prefetch::read(q, scan_interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
394
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // size and destination
a61af66fc99e Initial load
duke
parents:
diff changeset
396 size_t size = oop(q)->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
397 HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee();
a61af66fc99e Initial load
duke
parents:
diff changeset
398
a61af66fc99e Initial load
duke
parents:
diff changeset
399 // prefetch beyond compaction_top
a61af66fc99e Initial load
duke
parents:
diff changeset
400 Prefetch::write(compaction_top, copy_interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
401
a61af66fc99e Initial load
duke
parents:
diff changeset
402 // copy object and reinit its mark
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
403 VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, compaction_top));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
404 assert(q != compaction_top, "everything in this pass should be moving");
a61af66fc99e Initial load
duke
parents:
diff changeset
405 Copy::aligned_conjoint_words(q, compaction_top, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
406 oop(compaction_top)->init_mark();
a61af66fc99e Initial load
duke
parents:
diff changeset
407 assert(oop(compaction_top)->klass() != NULL, "should have a class");
a61af66fc99e Initial load
duke
parents:
diff changeset
408
a61af66fc99e Initial load
duke
parents:
diff changeset
409 debug_only(prev_q = q);
a61af66fc99e Initial load
duke
parents:
diff changeset
410 q += size;
a61af66fc99e Initial load
duke
parents:
diff changeset
411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
413
a61af66fc99e Initial load
duke
parents:
diff changeset
414 assert(compaction_top() >= space()->bottom() && compaction_top() <= space()->end(),
a61af66fc99e Initial load
duke
parents:
diff changeset
415 "should point inside space");
a61af66fc99e Initial load
duke
parents:
diff changeset
416 space()->set_top(compaction_top());
a61af66fc99e Initial load
duke
parents:
diff changeset
417
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
418 if (mangle_free_space) {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
419 space()->mangle_unused_area();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
420 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
421 }