Mercurial > hg > graal-compiler
annotate src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @ 2149:7e37af9d69ef
7011379: G1: overly long concurrent marking cycles
Summary: This changeset introduces filtering of SATB buffers at the point when they are about to be enqueued. If this filtering clears enough entries on each buffer, the buffer can then be re-used and not enqueued. This cuts down the number of SATB buffers that need to be processed by the concurrent marking threads.
Reviewed-by: johnc, ysr
author | tonyp |
---|---|
date | Wed, 19 Jan 2011 09:35:17 -0500 |
parents | f95d63e2154a |
children | 9afee0b9fc1d |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
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:
1489
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/symbolTable.hpp" | |
27 #include "classfile/systemDictionary.hpp" | |
28 #include "code/codeCache.hpp" | |
29 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" | |
30 #include "gc_implementation/parallelScavenge/generationSizer.hpp" | |
31 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp" | |
32 #include "gc_implementation/parallelScavenge/pcTasks.hpp" | |
33 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" | |
34 #include "gc_implementation/parallelScavenge/psCompactionManager.inline.hpp" | |
35 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp" | |
36 #include "gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp" | |
37 #include "gc_implementation/parallelScavenge/psOldGen.hpp" | |
38 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" | |
39 #include "gc_implementation/parallelScavenge/psPermGen.hpp" | |
40 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" | |
41 #include "gc_implementation/parallelScavenge/psScavenge.hpp" | |
42 #include "gc_implementation/parallelScavenge/psYoungGen.hpp" | |
43 #include "gc_implementation/shared/isGCActiveMark.hpp" | |
44 #include "gc_interface/gcCause.hpp" | |
45 #include "memory/gcLocker.inline.hpp" | |
46 #include "memory/referencePolicy.hpp" | |
47 #include "memory/referenceProcessor.hpp" | |
48 #include "oops/methodDataOop.hpp" | |
49 #include "oops/oop.inline.hpp" | |
50 #include "oops/oop.pcgc.inline.hpp" | |
51 #include "runtime/fprofiler.hpp" | |
52 #include "runtime/safepoint.hpp" | |
53 #include "runtime/vmThread.hpp" | |
54 #include "services/management.hpp" | |
55 #include "services/memoryService.hpp" | |
56 #include "utilities/events.hpp" | |
57 #include "utilities/stack.inline.hpp" | |
0 | 58 |
59 #include <math.h> | |
60 | |
61 // All sizes are in HeapWords. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
62 const size_t ParallelCompactData::Log2RegionSize = 9; // 512 words |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
63 const size_t ParallelCompactData::RegionSize = (size_t)1 << Log2RegionSize; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
64 const size_t ParallelCompactData::RegionSizeBytes = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
65 RegionSize << LogHeapWordSize; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
66 const size_t ParallelCompactData::RegionSizeOffsetMask = RegionSize - 1; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
67 const size_t ParallelCompactData::RegionAddrOffsetMask = RegionSizeBytes - 1; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
68 const size_t ParallelCompactData::RegionAddrMask = ~RegionAddrOffsetMask; |
0 | 69 |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
70 const ParallelCompactData::RegionData::region_sz_t |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
71 ParallelCompactData::RegionData::dc_shift = 27; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
72 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
73 const ParallelCompactData::RegionData::region_sz_t |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
74 ParallelCompactData::RegionData::dc_mask = ~0U << dc_shift; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
75 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
76 const ParallelCompactData::RegionData::region_sz_t |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
77 ParallelCompactData::RegionData::dc_one = 0x1U << dc_shift; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
78 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
79 const ParallelCompactData::RegionData::region_sz_t |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
80 ParallelCompactData::RegionData::los_mask = ~dc_mask; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
81 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
82 const ParallelCompactData::RegionData::region_sz_t |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
83 ParallelCompactData::RegionData::dc_claimed = 0x8U << dc_shift; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
84 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
85 const ParallelCompactData::RegionData::region_sz_t |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
86 ParallelCompactData::RegionData::dc_completed = 0xcU << dc_shift; |
0 | 87 |
88 SpaceInfo PSParallelCompact::_space_info[PSParallelCompact::last_space_id]; | |
89 bool PSParallelCompact::_print_phases = false; | |
90 | |
91 ReferenceProcessor* PSParallelCompact::_ref_processor = NULL; | |
92 klassOop PSParallelCompact::_updated_int_array_klass_obj = NULL; | |
93 | |
94 double PSParallelCompact::_dwl_mean; | |
95 double PSParallelCompact::_dwl_std_dev; | |
96 double PSParallelCompact::_dwl_first_term; | |
97 double PSParallelCompact::_dwl_adjustment; | |
98 #ifdef ASSERT | |
99 bool PSParallelCompact::_dwl_initialized = false; | |
100 #endif // #ifdef ASSERT | |
101 | |
102 #ifdef VALIDATE_MARK_SWEEP | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
103 GrowableArray<void*>* PSParallelCompact::_root_refs_stack = NULL; |
0 | 104 GrowableArray<oop> * PSParallelCompact::_live_oops = NULL; |
105 GrowableArray<oop> * PSParallelCompact::_live_oops_moved_to = NULL; | |
106 GrowableArray<size_t>* PSParallelCompact::_live_oops_size = NULL; | |
107 size_t PSParallelCompact::_live_oops_index = 0; | |
108 size_t PSParallelCompact::_live_oops_index_at_perm = 0; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
109 GrowableArray<void*>* PSParallelCompact::_other_refs_stack = NULL; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
110 GrowableArray<void*>* PSParallelCompact::_adjusted_pointers = NULL; |
0 | 111 bool PSParallelCompact::_pointer_tracking = false; |
112 bool PSParallelCompact::_root_tracking = true; | |
113 | |
114 GrowableArray<HeapWord*>* PSParallelCompact::_cur_gc_live_oops = NULL; | |
115 GrowableArray<HeapWord*>* PSParallelCompact::_cur_gc_live_oops_moved_to = NULL; | |
116 GrowableArray<size_t> * PSParallelCompact::_cur_gc_live_oops_size = NULL; | |
117 GrowableArray<HeapWord*>* PSParallelCompact::_last_gc_live_oops = NULL; | |
118 GrowableArray<HeapWord*>* PSParallelCompact::_last_gc_live_oops_moved_to = NULL; | |
119 GrowableArray<size_t> * PSParallelCompact::_last_gc_live_oops_size = NULL; | |
120 #endif | |
121 | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
122 void SplitInfo::record(size_t src_region_idx, size_t partial_obj_size, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
123 HeapWord* destination) |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
124 { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
125 assert(src_region_idx != 0, "invalid src_region_idx"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
126 assert(partial_obj_size != 0, "invalid partial_obj_size argument"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
127 assert(destination != NULL, "invalid destination argument"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
128 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
129 _src_region_idx = src_region_idx; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
130 _partial_obj_size = partial_obj_size; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
131 _destination = destination; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
132 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
133 // These fields may not be updated below, so make sure they're clear. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
134 assert(_dest_region_addr == NULL, "should have been cleared"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
135 assert(_first_src_addr == NULL, "should have been cleared"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
136 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
137 // Determine the number of destination regions for the partial object. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
138 HeapWord* const last_word = destination + partial_obj_size - 1; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
139 const ParallelCompactData& sd = PSParallelCompact::summary_data(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
140 HeapWord* const beg_region_addr = sd.region_align_down(destination); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
141 HeapWord* const end_region_addr = sd.region_align_down(last_word); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
142 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
143 if (beg_region_addr == end_region_addr) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
144 // One destination region. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
145 _destination_count = 1; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
146 if (end_region_addr == destination) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
147 // The destination falls on a region boundary, thus the first word of the |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
148 // partial object will be the first word copied to the destination region. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
149 _dest_region_addr = end_region_addr; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
150 _first_src_addr = sd.region_to_addr(src_region_idx); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
151 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
152 } else { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
153 // Two destination regions. When copied, the partial object will cross a |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
154 // destination region boundary, so a word somewhere within the partial |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
155 // object will be the first word copied to the second destination region. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
156 _destination_count = 2; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
157 _dest_region_addr = end_region_addr; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
158 const size_t ofs = pointer_delta(end_region_addr, destination); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
159 assert(ofs < _partial_obj_size, "sanity"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
160 _first_src_addr = sd.region_to_addr(src_region_idx) + ofs; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
161 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
162 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
163 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
164 void SplitInfo::clear() |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
165 { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
166 _src_region_idx = 0; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
167 _partial_obj_size = 0; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
168 _destination = NULL; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
169 _destination_count = 0; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
170 _dest_region_addr = NULL; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
171 _first_src_addr = NULL; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
172 assert(!is_valid(), "sanity"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
173 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
174 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
175 #ifdef ASSERT |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
176 void SplitInfo::verify_clear() |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
177 { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
178 assert(_src_region_idx == 0, "not clear"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
179 assert(_partial_obj_size == 0, "not clear"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
180 assert(_destination == NULL, "not clear"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
181 assert(_destination_count == 0, "not clear"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
182 assert(_dest_region_addr == NULL, "not clear"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
183 assert(_first_src_addr == NULL, "not clear"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
184 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
185 #endif // #ifdef ASSERT |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
186 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
187 |
0 | 188 #ifndef PRODUCT |
189 const char* PSParallelCompact::space_names[] = { | |
190 "perm", "old ", "eden", "from", "to " | |
191 }; | |
192 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
193 void PSParallelCompact::print_region_ranges() |
0 | 194 { |
195 tty->print_cr("space bottom top end new_top"); | |
196 tty->print_cr("------ ---------- ---------- ---------- ----------"); | |
197 | |
198 for (unsigned int id = 0; id < last_space_id; ++id) { | |
199 const MutableSpace* space = _space_info[id].space(); | |
200 tty->print_cr("%u %s " | |
264
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
201 SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " " |
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
202 SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ", |
0 | 203 id, space_names[id], |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
204 summary_data().addr_to_region_idx(space->bottom()), |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
205 summary_data().addr_to_region_idx(space->top()), |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
206 summary_data().addr_to_region_idx(space->end()), |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
207 summary_data().addr_to_region_idx(_space_info[id].new_top())); |
0 | 208 } |
209 } | |
210 | |
211 void | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
212 print_generic_summary_region(size_t i, const ParallelCompactData::RegionData* c) |
0 | 213 { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
214 #define REGION_IDX_FORMAT SIZE_FORMAT_W(7) |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
215 #define REGION_DATA_FORMAT SIZE_FORMAT_W(5) |
0 | 216 |
217 ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
218 size_t dci = c->destination() ? sd.addr_to_region_idx(c->destination()) : 0; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
219 tty->print_cr(REGION_IDX_FORMAT " " PTR_FORMAT " " |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
220 REGION_IDX_FORMAT " " PTR_FORMAT " " |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
221 REGION_DATA_FORMAT " " REGION_DATA_FORMAT " " |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
222 REGION_DATA_FORMAT " " REGION_IDX_FORMAT " %d", |
0 | 223 i, c->data_location(), dci, c->destination(), |
224 c->partial_obj_size(), c->live_obj_size(), | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
225 c->data_size(), c->source_region(), c->destination_count()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
226 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
227 #undef REGION_IDX_FORMAT |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
228 #undef REGION_DATA_FORMAT |
0 | 229 } |
230 | |
231 void | |
232 print_generic_summary_data(ParallelCompactData& summary_data, | |
233 HeapWord* const beg_addr, | |
234 HeapWord* const end_addr) | |
235 { | |
236 size_t total_words = 0; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
237 size_t i = summary_data.addr_to_region_idx(beg_addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
238 const size_t last = summary_data.addr_to_region_idx(end_addr); |
0 | 239 HeapWord* pdest = 0; |
240 | |
241 while (i <= last) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
242 ParallelCompactData::RegionData* c = summary_data.region(i); |
0 | 243 if (c->data_size() != 0 || c->destination() != pdest) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
244 print_generic_summary_region(i, c); |
0 | 245 total_words += c->data_size(); |
246 pdest = c->destination(); | |
247 } | |
248 ++i; | |
249 } | |
250 | |
251 tty->print_cr("summary_data_bytes=" SIZE_FORMAT, total_words * HeapWordSize); | |
252 } | |
253 | |
254 void | |
255 print_generic_summary_data(ParallelCompactData& summary_data, | |
256 SpaceInfo* space_info) | |
257 { | |
258 for (unsigned int id = 0; id < PSParallelCompact::last_space_id; ++id) { | |
259 const MutableSpace* space = space_info[id].space(); | |
260 print_generic_summary_data(summary_data, space->bottom(), | |
261 MAX2(space->top(), space_info[id].new_top())); | |
262 } | |
263 } | |
264 | |
265 void | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
266 print_initial_summary_region(size_t i, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
267 const ParallelCompactData::RegionData* c, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
268 bool newline = true) |
0 | 269 { |
264
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
270 tty->print(SIZE_FORMAT_W(5) " " PTR_FORMAT " " |
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
271 SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " |
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
272 SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d", |
0 | 273 i, c->destination(), |
274 c->partial_obj_size(), c->live_obj_size(), | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
275 c->data_size(), c->source_region(), c->destination_count()); |
0 | 276 if (newline) tty->cr(); |
277 } | |
278 | |
279 void | |
280 print_initial_summary_data(ParallelCompactData& summary_data, | |
281 const MutableSpace* space) { | |
282 if (space->top() == space->bottom()) { | |
283 return; | |
284 } | |
285 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
286 const size_t region_size = ParallelCompactData::RegionSize; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
287 typedef ParallelCompactData::RegionData RegionData; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
288 HeapWord* const top_aligned_up = summary_data.region_align_up(space->top()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
289 const size_t end_region = summary_data.addr_to_region_idx(top_aligned_up); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
290 const RegionData* c = summary_data.region(end_region - 1); |
0 | 291 HeapWord* end_addr = c->destination() + c->data_size(); |
292 const size_t live_in_space = pointer_delta(end_addr, space->bottom()); | |
293 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
294 // Print (and count) the full regions at the beginning of the space. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
295 size_t full_region_count = 0; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
296 size_t i = summary_data.addr_to_region_idx(space->bottom()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
297 while (i < end_region && summary_data.region(i)->data_size() == region_size) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
298 print_initial_summary_region(i, summary_data.region(i)); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
299 ++full_region_count; |
0 | 300 ++i; |
301 } | |
302 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
303 size_t live_to_right = live_in_space - full_region_count * region_size; |
0 | 304 |
305 double max_reclaimed_ratio = 0.0; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
306 size_t max_reclaimed_ratio_region = 0; |
0 | 307 size_t max_dead_to_right = 0; |
308 size_t max_live_to_right = 0; | |
309 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
310 // Print the 'reclaimed ratio' for regions while there is something live in |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
311 // the region or to the right of it. The remaining regions are empty (and |
0 | 312 // uninteresting), and computing the ratio will result in division by 0. |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
313 while (i < end_region && live_to_right > 0) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
314 c = summary_data.region(i); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
315 HeapWord* const region_addr = summary_data.region_to_addr(i); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
316 const size_t used_to_right = pointer_delta(space->top(), region_addr); |
0 | 317 const size_t dead_to_right = used_to_right - live_to_right; |
318 const double reclaimed_ratio = double(dead_to_right) / live_to_right; | |
319 | |
320 if (reclaimed_ratio > max_reclaimed_ratio) { | |
321 max_reclaimed_ratio = reclaimed_ratio; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
322 max_reclaimed_ratio_region = i; |
0 | 323 max_dead_to_right = dead_to_right; |
324 max_live_to_right = live_to_right; | |
325 } | |
326 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
327 print_initial_summary_region(i, c, false); |
264
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
328 tty->print_cr(" %12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10), |
0 | 329 reclaimed_ratio, dead_to_right, live_to_right); |
330 | |
331 live_to_right -= c->data_size(); | |
332 ++i; | |
333 } | |
334 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
335 // Any remaining regions are empty. Print one more if there is one. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
336 if (i < end_region) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
337 print_initial_summary_region(i, summary_data.region(i)); |
0 | 338 } |
339 | |
264
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
340 tty->print_cr("max: " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " " |
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
341 "l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f", |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
342 max_reclaimed_ratio_region, max_dead_to_right, |
0 | 343 max_live_to_right, max_reclaimed_ratio); |
344 } | |
345 | |
346 void | |
347 print_initial_summary_data(ParallelCompactData& summary_data, | |
348 SpaceInfo* space_info) { | |
349 unsigned int id = PSParallelCompact::perm_space_id; | |
350 const MutableSpace* space; | |
351 do { | |
352 space = space_info[id].space(); | |
353 print_initial_summary_data(summary_data, space); | |
354 } while (++id < PSParallelCompact::eden_space_id); | |
355 | |
356 do { | |
357 space = space_info[id].space(); | |
358 print_generic_summary_data(summary_data, space->bottom(), space->top()); | |
359 } while (++id < PSParallelCompact::last_space_id); | |
360 } | |
361 #endif // #ifndef PRODUCT | |
362 | |
363 #ifdef ASSERT | |
364 size_t add_obj_count; | |
365 size_t add_obj_size; | |
366 size_t mark_bitmap_count; | |
367 size_t mark_bitmap_size; | |
368 #endif // #ifdef ASSERT | |
369 | |
370 ParallelCompactData::ParallelCompactData() | |
371 { | |
372 _region_start = 0; | |
373 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
374 _region_vspace = 0; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
375 _region_data = 0; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
376 _region_count = 0; |
0 | 377 } |
378 | |
379 bool ParallelCompactData::initialize(MemRegion covered_region) | |
380 { | |
381 _region_start = covered_region.start(); | |
382 const size_t region_size = covered_region.word_size(); | |
383 DEBUG_ONLY(_region_end = _region_start + region_size;) | |
384 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
385 assert(region_align_down(_region_start) == _region_start, |
0 | 386 "region start not aligned"); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
387 assert((region_size & RegionSizeOffsetMask) == 0, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
388 "region size not a multiple of RegionSize"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
389 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
390 bool result = initialize_region_data(region_size); |
0 | 391 |
392 return result; | |
393 } | |
394 | |
395 PSVirtualSpace* | |
396 ParallelCompactData::create_vspace(size_t count, size_t element_size) | |
397 { | |
398 const size_t raw_bytes = count * element_size; | |
399 const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10); | |
400 const size_t granularity = os::vm_allocation_granularity(); | |
401 const size_t bytes = align_size_up(raw_bytes, MAX2(page_sz, granularity)); | |
402 | |
403 const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 : | |
404 MAX2(page_sz, granularity); | |
79
82db0859acbe
6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents:
0
diff
changeset
|
405 ReservedSpace rs(bytes, rs_align, rs_align > 0); |
0 | 406 os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(), |
407 rs.size()); | |
408 PSVirtualSpace* vspace = new PSVirtualSpace(rs, page_sz); | |
409 if (vspace != 0) { | |
410 if (vspace->expand_by(bytes)) { | |
411 return vspace; | |
412 } | |
413 delete vspace; | |
237
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
414 // Release memory reserved in the space. |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
415 rs.release(); |
0 | 416 } |
417 | |
418 return 0; | |
419 } | |
420 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
421 bool ParallelCompactData::initialize_region_data(size_t region_size) |
0 | 422 { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
423 const size_t count = (region_size + RegionSizeOffsetMask) >> Log2RegionSize; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
424 _region_vspace = create_vspace(count, sizeof(RegionData)); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
425 if (_region_vspace != 0) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
426 _region_data = (RegionData*)_region_vspace->reserved_low_addr(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
427 _region_count = count; |
0 | 428 return true; |
429 } | |
430 return false; | |
431 } | |
432 | |
433 void ParallelCompactData::clear() | |
434 { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
435 memset(_region_data, 0, _region_vspace->committed_size()); |
0 | 436 } |
437 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
438 void ParallelCompactData::clear_range(size_t beg_region, size_t end_region) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
439 assert(beg_region <= _region_count, "beg_region out of range"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
440 assert(end_region <= _region_count, "end_region out of range"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
441 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
442 const size_t region_cnt = end_region - beg_region; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
443 memset(_region_data + beg_region, 0, region_cnt * sizeof(RegionData)); |
0 | 444 } |
445 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
446 HeapWord* ParallelCompactData::partial_obj_end(size_t region_idx) const |
0 | 447 { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
448 const RegionData* cur_cp = region(region_idx); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
449 const RegionData* const end_cp = region(region_count() - 1); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
450 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
451 HeapWord* result = region_to_addr(region_idx); |
0 | 452 if (cur_cp < end_cp) { |
453 do { | |
454 result += cur_cp->partial_obj_size(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
455 } while (cur_cp->partial_obj_size() == RegionSize && ++cur_cp < end_cp); |
0 | 456 } |
457 return result; | |
458 } | |
459 | |
460 void ParallelCompactData::add_obj(HeapWord* addr, size_t len) | |
461 { | |
462 const size_t obj_ofs = pointer_delta(addr, _region_start); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
463 const size_t beg_region = obj_ofs >> Log2RegionSize; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
464 const size_t end_region = (obj_ofs + len - 1) >> Log2RegionSize; |
0 | 465 |
466 DEBUG_ONLY(Atomic::inc_ptr(&add_obj_count);) | |
467 DEBUG_ONLY(Atomic::add_ptr(len, &add_obj_size);) | |
468 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
469 if (beg_region == end_region) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
470 // All in one region. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
471 _region_data[beg_region].add_live_obj(len); |
0 | 472 return; |
473 } | |
474 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
475 // First region. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
476 const size_t beg_ofs = region_offset(addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
477 _region_data[beg_region].add_live_obj(RegionSize - beg_ofs); |
0 | 478 |
479 klassOop klass = ((oop)addr)->klass(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
480 // Middle regions--completely spanned by this object. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
481 for (size_t region = beg_region + 1; region < end_region; ++region) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
482 _region_data[region].set_partial_obj_size(RegionSize); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
483 _region_data[region].set_partial_obj_addr(addr); |
0 | 484 } |
485 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
486 // Last region. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
487 const size_t end_ofs = region_offset(addr + len - 1); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
488 _region_data[end_region].set_partial_obj_size(end_ofs + 1); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
489 _region_data[end_region].set_partial_obj_addr(addr); |
0 | 490 } |
491 | |
492 void | |
493 ParallelCompactData::summarize_dense_prefix(HeapWord* beg, HeapWord* end) | |
494 { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
495 assert(region_offset(beg) == 0, "not RegionSize aligned"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
496 assert(region_offset(end) == 0, "not RegionSize aligned"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
497 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
498 size_t cur_region = addr_to_region_idx(beg); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
499 const size_t end_region = addr_to_region_idx(end); |
0 | 500 HeapWord* addr = beg; |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
501 while (cur_region < end_region) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
502 _region_data[cur_region].set_destination(addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
503 _region_data[cur_region].set_destination_count(0); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
504 _region_data[cur_region].set_source_region(cur_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
505 _region_data[cur_region].set_data_location(addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
506 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
507 // Update live_obj_size so the region appears completely full. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
508 size_t live_size = RegionSize - _region_data[cur_region].partial_obj_size(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
509 _region_data[cur_region].set_live_obj_size(live_size); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
510 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
511 ++cur_region; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
512 addr += RegionSize; |
0 | 513 } |
514 } | |
515 | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
516 // Find the point at which a space can be split and, if necessary, record the |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
517 // split point. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
518 // |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
519 // If the current src region (which overflowed the destination space) doesn't |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
520 // have a partial object, the split point is at the beginning of the current src |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
521 // region (an "easy" split, no extra bookkeeping required). |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
522 // |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
523 // If the current src region has a partial object, the split point is in the |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
524 // region where that partial object starts (call it the split_region). If |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
525 // split_region has a partial object, then the split point is just after that |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
526 // partial object (a "hard" split where we have to record the split data and |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
527 // zero the partial_obj_size field). With a "hard" split, we know that the |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
528 // partial_obj ends within split_region because the partial object that caused |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
529 // the overflow starts in split_region. If split_region doesn't have a partial |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
530 // obj, then the split is at the beginning of split_region (another "easy" |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
531 // split). |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
532 HeapWord* |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
533 ParallelCompactData::summarize_split_space(size_t src_region, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
534 SplitInfo& split_info, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
535 HeapWord* destination, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
536 HeapWord* target_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
537 HeapWord** target_next) |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
538 { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
539 assert(destination <= target_end, "sanity"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
540 assert(destination + _region_data[src_region].data_size() > target_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
541 "region should not fit into target space"); |
696
f18338cf04b0
6810474: par compact - crash in summary_phase with very full heap
jcoomes
parents:
628
diff
changeset
|
542 assert(is_region_aligned(target_end), "sanity"); |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
543 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
544 size_t split_region = src_region; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
545 HeapWord* split_destination = destination; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
546 size_t partial_obj_size = _region_data[src_region].partial_obj_size(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
547 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
548 if (destination + partial_obj_size > target_end) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
549 // The split point is just after the partial object (if any) in the |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
550 // src_region that contains the start of the object that overflowed the |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
551 // destination space. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
552 // |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
553 // Find the start of the "overflow" object and set split_region to the |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
554 // region containing it. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
555 HeapWord* const overflow_obj = _region_data[src_region].partial_obj_addr(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
556 split_region = addr_to_region_idx(overflow_obj); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
557 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
558 // Clear the source_region field of all destination regions whose first word |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
559 // came from data after the split point (a non-null source_region field |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
560 // implies a region must be filled). |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
561 // |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
562 // An alternative to the simple loop below: clear during post_compact(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
563 // which uses memcpy instead of individual stores, and is easy to |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
564 // parallelize. (The downside is that it clears the entire RegionData |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
565 // object as opposed to just one field.) |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
566 // |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
567 // post_compact() would have to clear the summary data up to the highest |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
568 // address that was written during the summary phase, which would be |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
569 // |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
570 // max(top, max(new_top, clear_top)) |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
571 // |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
572 // where clear_top is a new field in SpaceInfo. Would have to set clear_top |
696
f18338cf04b0
6810474: par compact - crash in summary_phase with very full heap
jcoomes
parents:
628
diff
changeset
|
573 // to target_end. |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
574 const RegionData* const sr = region(split_region); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
575 const size_t beg_idx = |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
576 addr_to_region_idx(region_align_up(sr->destination() + |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
577 sr->partial_obj_size())); |
696
f18338cf04b0
6810474: par compact - crash in summary_phase with very full heap
jcoomes
parents:
628
diff
changeset
|
578 const size_t end_idx = addr_to_region_idx(target_end); |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
579 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
580 if (TraceParallelOldGCSummaryPhase) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
581 gclog_or_tty->print_cr("split: clearing source_region field in [" |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
582 SIZE_FORMAT ", " SIZE_FORMAT ")", |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
583 beg_idx, end_idx); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
584 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
585 for (size_t idx = beg_idx; idx < end_idx; ++idx) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
586 _region_data[idx].set_source_region(0); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
587 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
588 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
589 // Set split_destination and partial_obj_size to reflect the split region. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
590 split_destination = sr->destination(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
591 partial_obj_size = sr->partial_obj_size(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
592 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
593 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
594 // The split is recorded only if a partial object extends onto the region. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
595 if (partial_obj_size != 0) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
596 _region_data[split_region].set_partial_obj_size(0); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
597 split_info.record(split_region, partial_obj_size, split_destination); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
598 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
599 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
600 // Setup the continuation addresses. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
601 *target_next = split_destination + partial_obj_size; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
602 HeapWord* const source_next = region_to_addr(split_region) + partial_obj_size; |
0 | 603 |
604 if (TraceParallelOldGCSummaryPhase) { | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
605 const char * split_type = partial_obj_size == 0 ? "easy" : "hard"; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
606 gclog_or_tty->print_cr("%s split: src=" PTR_FORMAT " src_c=" SIZE_FORMAT |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
607 " pos=" SIZE_FORMAT, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
608 split_type, source_next, split_region, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
609 partial_obj_size); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
610 gclog_or_tty->print_cr("%s split: dst=" PTR_FORMAT " dst_c=" SIZE_FORMAT |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
611 " tn=" PTR_FORMAT, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
612 split_type, split_destination, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
613 addr_to_region_idx(split_destination), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
614 *target_next); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
615 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
616 if (partial_obj_size != 0) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
617 HeapWord* const po_beg = split_info.destination(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
618 HeapWord* const po_end = po_beg + split_info.partial_obj_size(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
619 gclog_or_tty->print_cr("%s split: " |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
620 "po_beg=" PTR_FORMAT " " SIZE_FORMAT " " |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
621 "po_end=" PTR_FORMAT " " SIZE_FORMAT, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
622 split_type, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
623 po_beg, addr_to_region_idx(po_beg), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
624 po_end, addr_to_region_idx(po_end)); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
625 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
626 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
627 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
628 return source_next; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
629 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
630 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
631 bool ParallelCompactData::summarize(SplitInfo& split_info, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
632 HeapWord* source_beg, HeapWord* source_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
633 HeapWord** source_next, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
634 HeapWord* target_beg, HeapWord* target_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
635 HeapWord** target_next) |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
636 { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
637 if (TraceParallelOldGCSummaryPhase) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
638 HeapWord* const source_next_val = source_next == NULL ? NULL : *source_next; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
639 tty->print_cr("sb=" PTR_FORMAT " se=" PTR_FORMAT " sn=" PTR_FORMAT |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
640 "tb=" PTR_FORMAT " te=" PTR_FORMAT " tn=" PTR_FORMAT, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
641 source_beg, source_end, source_next_val, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
642 target_beg, target_end, *target_next); |
0 | 643 } |
644 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
645 size_t cur_region = addr_to_region_idx(source_beg); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
646 const size_t end_region = addr_to_region_idx(region_align_up(source_end)); |
0 | 647 |
648 HeapWord *dest_addr = target_beg; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
649 while (cur_region < end_region) { |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
650 // The destination must be set even if the region has no data. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
651 _region_data[cur_region].set_destination(dest_addr); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
652 |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
653 size_t words = _region_data[cur_region].data_size(); |
0 | 654 if (words > 0) { |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
655 // If cur_region does not fit entirely into the target space, find a point |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
656 // at which the source space can be 'split' so that part is copied to the |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
657 // target space and the rest is copied elsewhere. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
658 if (dest_addr + words > target_end) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
659 assert(source_next != NULL, "source_next is NULL when splitting"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
660 *source_next = summarize_split_space(cur_region, split_info, dest_addr, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
661 target_end, target_next); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
662 return false; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
663 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
664 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
665 // Compute the destination_count for cur_region, and if necessary, update |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
666 // source_region for a destination region. The source_region field is |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
667 // updated if cur_region is the first (left-most) region to be copied to a |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
668 // destination region. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
669 // |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
670 // The destination_count calculation is a bit subtle. A region that has |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
671 // data that compacts into itself does not count itself as a destination. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
672 // This maintains the invariant that a zero count means the region is |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
673 // available and can be claimed and then filled. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
674 uint destination_count = 0; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
675 if (split_info.is_split(cur_region)) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
676 // The current region has been split: the partial object will be copied |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
677 // to one destination space and the remaining data will be copied to |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
678 // another destination space. Adjust the initial destination_count and, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
679 // if necessary, set the source_region field if the partial object will |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
680 // cross a destination region boundary. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
681 destination_count = split_info.destination_count(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
682 if (destination_count == 2) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
683 size_t dest_idx = addr_to_region_idx(split_info.dest_region_addr()); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
684 _region_data[dest_idx].set_source_region(cur_region); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
685 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
686 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
687 |
0 | 688 HeapWord* const last_addr = dest_addr + words - 1; |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
689 const size_t dest_region_1 = addr_to_region_idx(dest_addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
690 const size_t dest_region_2 = addr_to_region_idx(last_addr); |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
691 |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
692 // Initially assume that the destination regions will be the same and |
0 | 693 // adjust the value below if necessary. Under this assumption, if |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
694 // cur_region == dest_region_2, then cur_region will be compacted |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
695 // completely into itself. |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
696 destination_count += cur_region == dest_region_2 ? 0 : 1; |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
697 if (dest_region_1 != dest_region_2) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
698 // Destination regions differ; adjust destination_count. |
0 | 699 destination_count += 1; |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
700 // Data from cur_region will be copied to the start of dest_region_2. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
701 _region_data[dest_region_2].set_source_region(cur_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
702 } else if (region_offset(dest_addr) == 0) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
703 // Data from cur_region will be copied to the start of the destination |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
704 // region. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
705 _region_data[dest_region_1].set_source_region(cur_region); |
0 | 706 } |
707 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
708 _region_data[cur_region].set_destination_count(destination_count); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
709 _region_data[cur_region].set_data_location(region_to_addr(cur_region)); |
0 | 710 dest_addr += words; |
711 } | |
712 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
713 ++cur_region; |
0 | 714 } |
715 | |
716 *target_next = dest_addr; | |
717 return true; | |
718 } | |
719 | |
720 HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) { | |
721 assert(addr != NULL, "Should detect NULL oop earlier"); | |
722 assert(PSParallelCompact::gc_heap()->is_in(addr), "addr not in heap"); | |
723 #ifdef ASSERT | |
724 if (PSParallelCompact::mark_bitmap()->is_unmarked(addr)) { | |
725 gclog_or_tty->print_cr("calc_new_pointer:: addr " PTR_FORMAT, addr); | |
726 } | |
727 #endif | |
728 assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "obj not marked"); | |
729 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
730 // Region covering the object. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
731 size_t region_index = addr_to_region_idx(addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
732 const RegionData* const region_ptr = region(region_index); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
733 HeapWord* const region_addr = region_align_down(addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
734 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
735 assert(addr < region_addr + RegionSize, "Region does not cover object"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
736 assert(addr_to_region_ptr(region_addr) == region_ptr, "sanity check"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
737 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
738 HeapWord* result = region_ptr->destination(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
739 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
740 // If all the data in the region is live, then the new location of the object |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
741 // can be calculated from the destination of the region plus the offset of the |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
742 // object in the region. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
743 if (region_ptr->data_size() == RegionSize) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
744 result += pointer_delta(addr, region_addr); |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1489
diff
changeset
|
745 DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result);) |
0 | 746 return result; |
747 } | |
748 | |
749 // The new location of the object is | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
750 // region destination + |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
751 // size of the partial object extending onto the region + |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
752 // sizes of the live objects in the Region that are to the left of addr |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
753 const size_t partial_obj_size = region_ptr->partial_obj_size(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
754 HeapWord* const search_start = region_addr + partial_obj_size; |
0 | 755 |
756 const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap(); | |
757 size_t live_to_left = bitmap->live_words_in_range(search_start, oop(addr)); | |
758 | |
759 result += partial_obj_size + live_to_left; | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
760 DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result);) |
0 | 761 return result; |
762 } | |
763 | |
764 klassOop ParallelCompactData::calc_new_klass(klassOop old_klass) { | |
765 klassOop updated_klass; | |
766 if (PSParallelCompact::should_update_klass(old_klass)) { | |
767 updated_klass = (klassOop) calc_new_pointer(old_klass); | |
768 } else { | |
769 updated_klass = old_klass; | |
770 } | |
771 | |
772 return updated_klass; | |
773 } | |
774 | |
775 #ifdef ASSERT | |
776 void ParallelCompactData::verify_clear(const PSVirtualSpace* vspace) | |
777 { | |
778 const size_t* const beg = (const size_t*)vspace->committed_low_addr(); | |
779 const size_t* const end = (const size_t*)vspace->committed_high_addr(); | |
780 for (const size_t* p = beg; p < end; ++p) { | |
781 assert(*p == 0, "not zero"); | |
782 } | |
783 } | |
784 | |
785 void ParallelCompactData::verify_clear() | |
786 { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
787 verify_clear(_region_vspace); |
0 | 788 } |
789 #endif // #ifdef ASSERT | |
790 | |
791 #ifdef NOT_PRODUCT | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
792 ParallelCompactData::RegionData* debug_region(size_t region_index) { |
0 | 793 ParallelCompactData& sd = PSParallelCompact::summary_data(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
794 return sd.region(region_index); |
0 | 795 } |
796 #endif | |
797 | |
798 elapsedTimer PSParallelCompact::_accumulated_time; | |
799 unsigned int PSParallelCompact::_total_invocations = 0; | |
800 unsigned int PSParallelCompact::_maximum_compaction_gc_num = 0; | |
801 jlong PSParallelCompact::_time_of_last_gc = 0; | |
802 CollectorCounters* PSParallelCompact::_counters = NULL; | |
803 ParMarkBitMap PSParallelCompact::_mark_bitmap; | |
804 ParallelCompactData PSParallelCompact::_summary_data; | |
805 | |
806 PSParallelCompact::IsAliveClosure PSParallelCompact::_is_alive_closure; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
807 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
808 void PSParallelCompact::IsAliveClosure::do_object(oop p) { ShouldNotReachHere(); } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
809 bool PSParallelCompact::IsAliveClosure::do_object_b(oop p) { return mark_bitmap()->is_marked(p); } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
810 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
811 void PSParallelCompact::KeepAliveClosure::do_oop(oop* p) { PSParallelCompact::KeepAliveClosure::do_oop_work(p); } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
812 void PSParallelCompact::KeepAliveClosure::do_oop(narrowOop* p) { PSParallelCompact::KeepAliveClosure::do_oop_work(p); } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
813 |
0 | 814 PSParallelCompact::AdjustPointerClosure PSParallelCompact::_adjust_root_pointer_closure(true); |
815 PSParallelCompact::AdjustPointerClosure PSParallelCompact::_adjust_pointer_closure(false); | |
816 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
817 void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p, _is_root); } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
818 void PSParallelCompact::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
819 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
997
diff
changeset
|
820 void PSParallelCompact::FollowStackClosure::do_void() { _compaction_manager->follow_marking_stacks(); } |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
821 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
822 void PSParallelCompact::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(_compaction_manager, p); } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
823 void PSParallelCompact::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(_compaction_manager, p); } |
0 | 824 |
825 void PSParallelCompact::post_initialize() { | |
826 ParallelScavengeHeap* heap = gc_heap(); | |
827 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
828 | |
829 MemRegion mr = heap->reserved_region(); | |
830 _ref_processor = ReferenceProcessor::create_ref_processor( | |
831 mr, // span | |
832 true, // atomic_discovery | |
833 true, // mt_discovery | |
834 &_is_alive_closure, | |
835 ParallelGCThreads, | |
836 ParallelRefProcEnabled); | |
837 _counters = new CollectorCounters("PSParallelCompact", 1); | |
838 | |
839 // Initialize static fields in ParCompactionManager. | |
840 ParCompactionManager::initialize(mark_bitmap()); | |
841 } | |
842 | |
843 bool PSParallelCompact::initialize() { | |
844 ParallelScavengeHeap* heap = gc_heap(); | |
845 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
846 MemRegion mr = heap->reserved_region(); | |
847 | |
848 // Was the old gen get allocated successfully? | |
849 if (!heap->old_gen()->is_allocated()) { | |
850 return false; | |
851 } | |
852 | |
853 initialize_space_info(); | |
854 initialize_dead_wood_limiter(); | |
855 | |
856 if (!_mark_bitmap.initialize(mr)) { | |
857 vm_shutdown_during_initialization("Unable to allocate bit map for " | |
858 "parallel garbage collection for the requested heap size."); | |
859 return false; | |
860 } | |
861 | |
862 if (!_summary_data.initialize(mr)) { | |
863 vm_shutdown_during_initialization("Unable to allocate tables for " | |
864 "parallel garbage collection for the requested heap size."); | |
865 return false; | |
866 } | |
867 | |
868 return true; | |
869 } | |
870 | |
871 void PSParallelCompact::initialize_space_info() | |
872 { | |
873 memset(&_space_info, 0, sizeof(_space_info)); | |
874 | |
875 ParallelScavengeHeap* heap = gc_heap(); | |
876 PSYoungGen* young_gen = heap->young_gen(); | |
877 MutableSpace* perm_space = heap->perm_gen()->object_space(); | |
878 | |
879 _space_info[perm_space_id].set_space(perm_space); | |
880 _space_info[old_space_id].set_space(heap->old_gen()->object_space()); | |
881 _space_info[eden_space_id].set_space(young_gen->eden_space()); | |
882 _space_info[from_space_id].set_space(young_gen->from_space()); | |
883 _space_info[to_space_id].set_space(young_gen->to_space()); | |
884 | |
885 _space_info[perm_space_id].set_start_array(heap->perm_gen()->start_array()); | |
886 _space_info[old_space_id].set_start_array(heap->old_gen()->start_array()); | |
887 | |
888 _space_info[perm_space_id].set_min_dense_prefix(perm_space->top()); | |
889 if (TraceParallelOldGCDensePrefix) { | |
890 tty->print_cr("perm min_dense_prefix=" PTR_FORMAT, | |
891 _space_info[perm_space_id].min_dense_prefix()); | |
892 } | |
893 } | |
894 | |
895 void PSParallelCompact::initialize_dead_wood_limiter() | |
896 { | |
897 const size_t max = 100; | |
898 _dwl_mean = double(MIN2(ParallelOldDeadWoodLimiterMean, max)) / 100.0; | |
899 _dwl_std_dev = double(MIN2(ParallelOldDeadWoodLimiterStdDev, max)) / 100.0; | |
900 _dwl_first_term = 1.0 / (sqrt(2.0 * M_PI) * _dwl_std_dev); | |
901 DEBUG_ONLY(_dwl_initialized = true;) | |
902 _dwl_adjustment = normal_distribution(1.0); | |
903 } | |
904 | |
905 // Simple class for storing info about the heap at the start of GC, to be used | |
906 // after GC for comparison/printing. | |
907 class PreGCValues { | |
908 public: | |
909 PreGCValues() { } | |
910 PreGCValues(ParallelScavengeHeap* heap) { fill(heap); } | |
911 | |
912 void fill(ParallelScavengeHeap* heap) { | |
913 _heap_used = heap->used(); | |
914 _young_gen_used = heap->young_gen()->used_in_bytes(); | |
915 _old_gen_used = heap->old_gen()->used_in_bytes(); | |
916 _perm_gen_used = heap->perm_gen()->used_in_bytes(); | |
917 }; | |
918 | |
919 size_t heap_used() const { return _heap_used; } | |
920 size_t young_gen_used() const { return _young_gen_used; } | |
921 size_t old_gen_used() const { return _old_gen_used; } | |
922 size_t perm_gen_used() const { return _perm_gen_used; } | |
923 | |
924 private: | |
925 size_t _heap_used; | |
926 size_t _young_gen_used; | |
927 size_t _old_gen_used; | |
928 size_t _perm_gen_used; | |
929 }; | |
930 | |
931 void | |
932 PSParallelCompact::clear_data_covering_space(SpaceId id) | |
933 { | |
934 // At this point, top is the value before GC, new_top() is the value that will | |
935 // be set at the end of GC. The marking bitmap is cleared to top; nothing | |
936 // should be marked above top. The summary data is cleared to the larger of | |
937 // top & new_top. | |
938 MutableSpace* const space = _space_info[id].space(); | |
939 HeapWord* const bot = space->bottom(); | |
940 HeapWord* const top = space->top(); | |
941 HeapWord* const max_top = MAX2(top, _space_info[id].new_top()); | |
942 | |
943 const idx_t beg_bit = _mark_bitmap.addr_to_bit(bot); | |
944 const idx_t end_bit = BitMap::word_align_up(_mark_bitmap.addr_to_bit(top)); | |
945 _mark_bitmap.clear_range(beg_bit, end_bit); | |
946 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
947 const size_t beg_region = _summary_data.addr_to_region_idx(bot); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
948 const size_t end_region = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
949 _summary_data.addr_to_region_idx(_summary_data.region_align_up(max_top)); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
950 _summary_data.clear_range(beg_region, end_region); |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
951 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
952 // Clear the data used to 'split' regions. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
953 SplitInfo& split_info = _space_info[id].split_info(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
954 if (split_info.is_valid()) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
955 split_info.clear(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
956 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
957 DEBUG_ONLY(split_info.verify_clear();) |
0 | 958 } |
959 | |
960 void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values) | |
961 { | |
962 // Update the from & to space pointers in space_info, since they are swapped | |
963 // at each young gen gc. Do the update unconditionally (even though a | |
964 // promotion failure does not swap spaces) because an unknown number of minor | |
965 // collections will have swapped the spaces an unknown number of times. | |
966 TraceTime tm("pre compact", print_phases(), true, gclog_or_tty); | |
967 ParallelScavengeHeap* heap = gc_heap(); | |
968 _space_info[from_space_id].set_space(heap->young_gen()->from_space()); | |
969 _space_info[to_space_id].set_space(heap->young_gen()->to_space()); | |
970 | |
971 pre_gc_values->fill(heap); | |
972 | |
973 ParCompactionManager::reset(); | |
974 NOT_PRODUCT(_mark_bitmap.reset_counters()); | |
975 DEBUG_ONLY(add_obj_count = add_obj_size = 0;) | |
976 DEBUG_ONLY(mark_bitmap_count = mark_bitmap_size = 0;) | |
977 | |
978 // Increment the invocation count | |
139
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
0
diff
changeset
|
979 heap->increment_total_collections(true); |
0 | 980 |
981 // We need to track unique mark sweep invocations as well. | |
982 _total_invocations++; | |
983 | |
984 if (PrintHeapAtGC) { | |
985 Universe::print_heap_before_gc(); | |
986 } | |
987 | |
988 // Fill in TLABs | |
989 heap->accumulate_statistics_all_tlabs(); | |
990 heap->ensure_parsability(true); // retire TLABs | |
991 | |
992 if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) { | |
993 HandleMark hm; // Discard invalid handles created during verification | |
994 gclog_or_tty->print(" VerifyBeforeGC:"); | |
995 Universe::verify(true); | |
996 } | |
997 | |
998 // Verify object start arrays | |
999 if (VerifyObjectStartArray && | |
1000 VerifyBeforeGC) { | |
1001 heap->old_gen()->verify_object_start_array(); | |
1002 heap->perm_gen()->verify_object_start_array(); | |
1003 } | |
1004 | |
1005 DEBUG_ONLY(mark_bitmap()->verify_clear();) | |
1006 DEBUG_ONLY(summary_data().verify_clear();) | |
210 | 1007 |
1008 // Have worker threads release resources the next time they run a task. | |
1009 gc_task_manager()->release_all_resources(); | |
0 | 1010 } |
1011 | |
1012 void PSParallelCompact::post_compact() | |
1013 { | |
1014 TraceTime tm("post compact", print_phases(), true, gclog_or_tty); | |
1015 | |
1016 for (unsigned int id = perm_space_id; id < last_space_id; ++id) { | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1017 // Clear the marking bitmap, summary data and split info. |
0 | 1018 clear_data_covering_space(SpaceId(id)); |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1019 // Update top(). Must be done after clearing the bitmap and summary data. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1020 _space_info[id].publish_new_top(); |
0 | 1021 } |
1022 | |
1023 MutableSpace* const eden_space = _space_info[eden_space_id].space(); | |
1024 MutableSpace* const from_space = _space_info[from_space_id].space(); | |
1025 MutableSpace* const to_space = _space_info[to_space_id].space(); | |
1026 | |
1027 ParallelScavengeHeap* heap = gc_heap(); | |
1028 bool eden_empty = eden_space->is_empty(); | |
1029 if (!eden_empty) { | |
1030 eden_empty = absorb_live_data_from_eden(heap->size_policy(), | |
1031 heap->young_gen(), heap->old_gen()); | |
1032 } | |
1033 | |
1034 // Update heap occupancy information which is used as input to the soft ref | |
1035 // clearing policy at the next gc. | |
1036 Universe::update_heap_info_at_gc(); | |
1037 | |
1038 bool young_gen_empty = eden_empty && from_space->is_empty() && | |
1039 to_space->is_empty(); | |
1040 | |
1041 BarrierSet* bs = heap->barrier_set(); | |
1042 if (bs->is_a(BarrierSet::ModRef)) { | |
1043 ModRefBarrierSet* modBS = (ModRefBarrierSet*)bs; | |
1044 MemRegion old_mr = heap->old_gen()->reserved(); | |
1045 MemRegion perm_mr = heap->perm_gen()->reserved(); | |
1046 assert(perm_mr.end() <= old_mr.start(), "Generations out of order"); | |
1047 | |
1048 if (young_gen_empty) { | |
1049 modBS->clear(MemRegion(perm_mr.start(), old_mr.end())); | |
1050 } else { | |
1051 modBS->invalidate(MemRegion(perm_mr.start(), old_mr.end())); | |
1052 } | |
1053 } | |
1054 | |
1055 Threads::gc_epilogue(); | |
1056 CodeCache::gc_epilogue(); | |
1057 | |
1058 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); | |
1059 | |
1060 ref_processor()->enqueue_discovered_references(NULL); | |
1061 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
1062 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
1063 heap->gen_mangle_unused_area(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
1064 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
1065 |
0 | 1066 // Update time of last GC |
1067 reset_millis_since_last_gc(); | |
1068 } | |
1069 | |
1070 HeapWord* | |
1071 PSParallelCompact::compute_dense_prefix_via_density(const SpaceId id, | |
1072 bool maximum_compaction) | |
1073 { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1074 const size_t region_size = ParallelCompactData::RegionSize; |
0 | 1075 const ParallelCompactData& sd = summary_data(); |
1076 | |
1077 const MutableSpace* const space = _space_info[id].space(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1078 HeapWord* const top_aligned_up = sd.region_align_up(space->top()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1079 const RegionData* const beg_cp = sd.addr_to_region_ptr(space->bottom()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1080 const RegionData* const end_cp = sd.addr_to_region_ptr(top_aligned_up); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1081 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1082 // Skip full regions at the beginning of the space--they are necessarily part |
0 | 1083 // of the dense prefix. |
1084 size_t full_count = 0; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1085 const RegionData* cp; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1086 for (cp = beg_cp; cp < end_cp && cp->data_size() == region_size; ++cp) { |
0 | 1087 ++full_count; |
1088 } | |
1089 | |
1090 assert(total_invocations() >= _maximum_compaction_gc_num, "sanity"); | |
1091 const size_t gcs_since_max = total_invocations() - _maximum_compaction_gc_num; | |
1092 const bool interval_ended = gcs_since_max > HeapMaximumCompactionInterval; | |
1093 if (maximum_compaction || cp == end_cp || interval_ended) { | |
1094 _maximum_compaction_gc_num = total_invocations(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1095 return sd.region_to_addr(cp); |
0 | 1096 } |
1097 | |
1098 HeapWord* const new_top = _space_info[id].new_top(); | |
1099 const size_t space_live = pointer_delta(new_top, space->bottom()); | |
1100 const size_t space_used = space->used_in_words(); | |
1101 const size_t space_capacity = space->capacity_in_words(); | |
1102 | |
1103 const double cur_density = double(space_live) / space_capacity; | |
1104 const double deadwood_density = | |
1105 (1.0 - cur_density) * (1.0 - cur_density) * cur_density * cur_density; | |
1106 const size_t deadwood_goal = size_t(space_capacity * deadwood_density); | |
1107 | |
1108 if (TraceParallelOldGCDensePrefix) { | |
1109 tty->print_cr("cur_dens=%5.3f dw_dens=%5.3f dw_goal=" SIZE_FORMAT, | |
1110 cur_density, deadwood_density, deadwood_goal); | |
1111 tty->print_cr("space_live=" SIZE_FORMAT " " "space_used=" SIZE_FORMAT " " | |
1112 "space_cap=" SIZE_FORMAT, | |
1113 space_live, space_used, | |
1114 space_capacity); | |
1115 } | |
1116 | |
1117 // XXX - Use binary search? | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1118 HeapWord* dense_prefix = sd.region_to_addr(cp); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1119 const RegionData* full_cp = cp; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1120 const RegionData* const top_cp = sd.addr_to_region_ptr(space->top() - 1); |
0 | 1121 while (cp < end_cp) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1122 HeapWord* region_destination = cp->destination(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1123 const size_t cur_deadwood = pointer_delta(dense_prefix, region_destination); |
0 | 1124 if (TraceParallelOldGCDensePrefix && Verbose) { |
264
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
1125 tty->print_cr("c#=" SIZE_FORMAT_W(4) " dst=" PTR_FORMAT " " |
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
1126 "dp=" SIZE_FORMAT_W(8) " " "cdw=" SIZE_FORMAT_W(8), |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1127 sd.region(cp), region_destination, |
0 | 1128 dense_prefix, cur_deadwood); |
1129 } | |
1130 | |
1131 if (cur_deadwood >= deadwood_goal) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1132 // Found the region that has the correct amount of deadwood to the left. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1133 // This typically occurs after crossing a fairly sparse set of regions, so |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1134 // iterate backwards over those sparse regions, looking for the region |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1135 // that has the lowest density of live objects 'to the right.' |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1136 size_t space_to_left = sd.region(cp) * region_size; |
0 | 1137 size_t live_to_left = space_to_left - cur_deadwood; |
1138 size_t space_to_right = space_capacity - space_to_left; | |
1139 size_t live_to_right = space_live - live_to_left; | |
1140 double density_to_right = double(live_to_right) / space_to_right; | |
1141 while (cp > full_cp) { | |
1142 --cp; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1143 const size_t prev_region_live_to_right = live_to_right - |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1144 cp->data_size(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1145 const size_t prev_region_space_to_right = space_to_right + region_size; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1146 double prev_region_density_to_right = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1147 double(prev_region_live_to_right) / prev_region_space_to_right; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1148 if (density_to_right <= prev_region_density_to_right) { |
0 | 1149 return dense_prefix; |
1150 } | |
1151 if (TraceParallelOldGCDensePrefix && Verbose) { | |
264
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
1152 tty->print_cr("backing up from c=" SIZE_FORMAT_W(4) " d2r=%10.8f " |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1153 "pc_d2r=%10.8f", sd.region(cp), density_to_right, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1154 prev_region_density_to_right); |
0 | 1155 } |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1156 dense_prefix -= region_size; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1157 live_to_right = prev_region_live_to_right; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1158 space_to_right = prev_region_space_to_right; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1159 density_to_right = prev_region_density_to_right; |
0 | 1160 } |
1161 return dense_prefix; | |
1162 } | |
1163 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1164 dense_prefix += region_size; |
0 | 1165 ++cp; |
1166 } | |
1167 | |
1168 return dense_prefix; | |
1169 } | |
1170 | |
1171 #ifndef PRODUCT | |
1172 void PSParallelCompact::print_dense_prefix_stats(const char* const algorithm, | |
1173 const SpaceId id, | |
1174 const bool maximum_compaction, | |
1175 HeapWord* const addr) | |
1176 { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1177 const size_t region_idx = summary_data().addr_to_region_idx(addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1178 RegionData* const cp = summary_data().region(region_idx); |
0 | 1179 const MutableSpace* const space = _space_info[id].space(); |
1180 HeapWord* const new_top = _space_info[id].new_top(); | |
1181 | |
1182 const size_t space_live = pointer_delta(new_top, space->bottom()); | |
1183 const size_t dead_to_left = pointer_delta(addr, cp->destination()); | |
1184 const size_t space_cap = space->capacity_in_words(); | |
1185 const double dead_to_left_pct = double(dead_to_left) / space_cap; | |
1186 const size_t live_to_right = new_top - cp->destination(); | |
1187 const size_t dead_to_right = space->top() - addr - live_to_right; | |
1188 | |
264
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
1189 tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W(5) " " |
0 | 1190 "spl=" SIZE_FORMAT " " |
1191 "d2l=" SIZE_FORMAT " d2l%%=%6.4f " | |
1192 "d2r=" SIZE_FORMAT " l2r=" SIZE_FORMAT | |
1193 " ratio=%10.8f", | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1194 algorithm, addr, region_idx, |
0 | 1195 space_live, |
1196 dead_to_left, dead_to_left_pct, | |
1197 dead_to_right, live_to_right, | |
1198 double(dead_to_right) / live_to_right); | |
1199 } | |
1200 #endif // #ifndef PRODUCT | |
1201 | |
1202 // Return a fraction indicating how much of the generation can be treated as | |
1203 // "dead wood" (i.e., not reclaimed). The function uses a normal distribution | |
1204 // based on the density of live objects in the generation to determine a limit, | |
1205 // which is then adjusted so the return value is min_percent when the density is | |
1206 // 1. | |
1207 // | |
1208 // The following table shows some return values for a different values of the | |
1209 // standard deviation (ParallelOldDeadWoodLimiterStdDev); the mean is 0.5 and | |
1210 // min_percent is 1. | |
1211 // | |
1212 // fraction allowed as dead wood | |
1213 // ----------------------------------------------------------------- | |
1214 // density std_dev=70 std_dev=75 std_dev=80 std_dev=85 std_dev=90 std_dev=95 | |
1215 // ------- ---------- ---------- ---------- ---------- ---------- ---------- | |
1216 // 0.00000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 | |
1217 // 0.05000 0.03193096 0.02836880 0.02550828 0.02319280 0.02130337 0.01974941 | |
1218 // 0.10000 0.05247504 0.04547452 0.03988045 0.03537016 0.03170171 0.02869272 | |
1219 // 0.15000 0.07135702 0.06111390 0.05296419 0.04641639 0.04110601 0.03676066 | |
1220 // 0.20000 0.08831616 0.07509618 0.06461766 0.05622444 0.04943437 0.04388975 | |
1221 // 0.25000 0.10311208 0.08724696 0.07471205 0.06469760 0.05661313 0.05002313 | |
1222 // 0.30000 0.11553050 0.09741183 0.08313394 0.07175114 0.06257797 0.05511132 | |
1223 // 0.35000 0.12538832 0.10545958 0.08978741 0.07731366 0.06727491 0.05911289 | |
1224 // 0.40000 0.13253818 0.11128511 0.09459590 0.08132834 0.07066107 0.06199500 | |
1225 // 0.45000 0.13687208 0.11481163 0.09750361 0.08375387 0.07270534 0.06373386 | |
1226 // 0.50000 0.13832410 0.11599237 0.09847664 0.08456518 0.07338887 0.06431510 | |
1227 // 0.55000 0.13687208 0.11481163 0.09750361 0.08375387 0.07270534 0.06373386 | |
1228 // 0.60000 0.13253818 0.11128511 0.09459590 0.08132834 0.07066107 0.06199500 | |
1229 // 0.65000 0.12538832 0.10545958 0.08978741 0.07731366 0.06727491 0.05911289 | |
1230 // 0.70000 0.11553050 0.09741183 0.08313394 0.07175114 0.06257797 0.05511132 | |
1231 // 0.75000 0.10311208 0.08724696 0.07471205 0.06469760 0.05661313 0.05002313 | |
1232 // 0.80000 0.08831616 0.07509618 0.06461766 0.05622444 0.04943437 0.04388975 | |
1233 // 0.85000 0.07135702 0.06111390 0.05296419 0.04641639 0.04110601 0.03676066 | |
1234 // 0.90000 0.05247504 0.04547452 0.03988045 0.03537016 0.03170171 0.02869272 | |
1235 // 0.95000 0.03193096 0.02836880 0.02550828 0.02319280 0.02130337 0.01974941 | |
1236 // 1.00000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 | |
1237 | |
1238 double PSParallelCompact::dead_wood_limiter(double density, size_t min_percent) | |
1239 { | |
1240 assert(_dwl_initialized, "uninitialized"); | |
1241 | |
1242 // The raw limit is the value of the normal distribution at x = density. | |
1243 const double raw_limit = normal_distribution(density); | |
1244 | |
1245 // Adjust the raw limit so it becomes the minimum when the density is 1. | |
1246 // | |
1247 // First subtract the adjustment value (which is simply the precomputed value | |
1248 // normal_distribution(1.0)); this yields a value of 0 when the density is 1. | |
1249 // Then add the minimum value, so the minimum is returned when the density is | |
1250 // 1. Finally, prevent negative values, which occur when the mean is not 0.5. | |
1251 const double min = double(min_percent) / 100.0; | |
1252 const double limit = raw_limit - _dwl_adjustment + min; | |
1253 return MAX2(limit, 0.0); | |
1254 } | |
1255 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1256 ParallelCompactData::RegionData* |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1257 PSParallelCompact::first_dead_space_region(const RegionData* beg, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1258 const RegionData* end) |
0 | 1259 { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1260 const size_t region_size = ParallelCompactData::RegionSize; |
0 | 1261 ParallelCompactData& sd = summary_data(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1262 size_t left = sd.region(beg); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1263 size_t right = end > beg ? sd.region(end) - 1 : left; |
0 | 1264 |
1265 // Binary search. | |
1266 while (left < right) { | |
1267 // Equivalent to (left + right) / 2, but does not overflow. | |
1268 const size_t middle = left + (right - left) / 2; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1269 RegionData* const middle_ptr = sd.region(middle); |
0 | 1270 HeapWord* const dest = middle_ptr->destination(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1271 HeapWord* const addr = sd.region_to_addr(middle); |
0 | 1272 assert(dest != NULL, "sanity"); |
1273 assert(dest <= addr, "must move left"); | |
1274 | |
1275 if (middle > left && dest < addr) { | |
1276 right = middle - 1; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1277 } else if (middle < right && middle_ptr->data_size() == region_size) { |
0 | 1278 left = middle + 1; |
1279 } else { | |
1280 return middle_ptr; | |
1281 } | |
1282 } | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1283 return sd.region(left); |
0 | 1284 } |
1285 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1286 ParallelCompactData::RegionData* |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1287 PSParallelCompact::dead_wood_limit_region(const RegionData* beg, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1288 const RegionData* end, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1289 size_t dead_words) |
0 | 1290 { |
1291 ParallelCompactData& sd = summary_data(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1292 size_t left = sd.region(beg); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1293 size_t right = end > beg ? sd.region(end) - 1 : left; |
0 | 1294 |
1295 // Binary search. | |
1296 while (left < right) { | |
1297 // Equivalent to (left + right) / 2, but does not overflow. | |
1298 const size_t middle = left + (right - left) / 2; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1299 RegionData* const middle_ptr = sd.region(middle); |
0 | 1300 HeapWord* const dest = middle_ptr->destination(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1301 HeapWord* const addr = sd.region_to_addr(middle); |
0 | 1302 assert(dest != NULL, "sanity"); |
1303 assert(dest <= addr, "must move left"); | |
1304 | |
1305 const size_t dead_to_left = pointer_delta(addr, dest); | |
1306 if (middle > left && dead_to_left > dead_words) { | |
1307 right = middle - 1; | |
1308 } else if (middle < right && dead_to_left < dead_words) { | |
1309 left = middle + 1; | |
1310 } else { | |
1311 return middle_ptr; | |
1312 } | |
1313 } | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1314 return sd.region(left); |
0 | 1315 } |
1316 | |
1317 // The result is valid during the summary phase, after the initial summarization | |
1318 // of each space into itself, and before final summarization. | |
1319 inline double | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1320 PSParallelCompact::reclaimed_ratio(const RegionData* const cp, |
0 | 1321 HeapWord* const bottom, |
1322 HeapWord* const top, | |
1323 HeapWord* const new_top) | |
1324 { | |
1325 ParallelCompactData& sd = summary_data(); | |
1326 | |
1327 assert(cp != NULL, "sanity"); | |
1328 assert(bottom != NULL, "sanity"); | |
1329 assert(top != NULL, "sanity"); | |
1330 assert(new_top != NULL, "sanity"); | |
1331 assert(top >= new_top, "summary data problem?"); | |
1332 assert(new_top > bottom, "space is empty; should not be here"); | |
1333 assert(new_top >= cp->destination(), "sanity"); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1334 assert(top >= sd.region_to_addr(cp), "sanity"); |
0 | 1335 |
1336 HeapWord* const destination = cp->destination(); | |
1337 const size_t dense_prefix_live = pointer_delta(destination, bottom); | |
1338 const size_t compacted_region_live = pointer_delta(new_top, destination); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1339 const size_t compacted_region_used = pointer_delta(top, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1340 sd.region_to_addr(cp)); |
0 | 1341 const size_t reclaimable = compacted_region_used - compacted_region_live; |
1342 | |
1343 const double divisor = dense_prefix_live + 1.25 * compacted_region_live; | |
1344 return double(reclaimable) / divisor; | |
1345 } | |
1346 | |
1347 // Return the address of the end of the dense prefix, a.k.a. the start of the | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1348 // compacted region. The address is always on a region boundary. |
0 | 1349 // |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1350 // Completely full regions at the left are skipped, since no compaction can |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1351 // occur in those regions. Then the maximum amount of dead wood to allow is |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1352 // computed, based on the density (amount live / capacity) of the generation; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1353 // the region with approximately that amount of dead space to the left is |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1354 // identified as the limit region. Regions between the last completely full |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1355 // region and the limit region are scanned and the one that has the best |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1356 // (maximum) reclaimed_ratio() is selected. |
0 | 1357 HeapWord* |
1358 PSParallelCompact::compute_dense_prefix(const SpaceId id, | |
1359 bool maximum_compaction) | |
1360 { | |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1361 if (ParallelOldGCSplitALot) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1362 if (_space_info[id].dense_prefix() != _space_info[id].space()->bottom()) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1363 // The value was chosen to provoke splitting a young gen space; use it. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1364 return _space_info[id].dense_prefix(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1365 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1366 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1367 |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1368 const size_t region_size = ParallelCompactData::RegionSize; |
0 | 1369 const ParallelCompactData& sd = summary_data(); |
1370 | |
1371 const MutableSpace* const space = _space_info[id].space(); | |
1372 HeapWord* const top = space->top(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1373 HeapWord* const top_aligned_up = sd.region_align_up(top); |
0 | 1374 HeapWord* const new_top = _space_info[id].new_top(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1375 HeapWord* const new_top_aligned_up = sd.region_align_up(new_top); |
0 | 1376 HeapWord* const bottom = space->bottom(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1377 const RegionData* const beg_cp = sd.addr_to_region_ptr(bottom); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1378 const RegionData* const top_cp = sd.addr_to_region_ptr(top_aligned_up); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1379 const RegionData* const new_top_cp = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1380 sd.addr_to_region_ptr(new_top_aligned_up); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1381 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1382 // Skip full regions at the beginning of the space--they are necessarily part |
0 | 1383 // of the dense prefix. |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1384 const RegionData* const full_cp = first_dead_space_region(beg_cp, new_top_cp); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1385 assert(full_cp->destination() == sd.region_to_addr(full_cp) || |
0 | 1386 space->is_empty(), "no dead space allowed to the left"); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1387 assert(full_cp->data_size() < region_size || full_cp == new_top_cp - 1, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1388 "region must have dead space"); |
0 | 1389 |
1390 // The gc number is saved whenever a maximum compaction is done, and used to | |
1391 // determine when the maximum compaction interval has expired. This avoids | |
1392 // successive max compactions for different reasons. | |
1393 assert(total_invocations() >= _maximum_compaction_gc_num, "sanity"); | |
1394 const size_t gcs_since_max = total_invocations() - _maximum_compaction_gc_num; | |
1395 const bool interval_ended = gcs_since_max > HeapMaximumCompactionInterval || | |
1396 total_invocations() == HeapFirstMaximumCompactionCount; | |
1397 if (maximum_compaction || full_cp == top_cp || interval_ended) { | |
1398 _maximum_compaction_gc_num = total_invocations(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1399 return sd.region_to_addr(full_cp); |
0 | 1400 } |
1401 | |
1402 const size_t space_live = pointer_delta(new_top, bottom); | |
1403 const size_t space_used = space->used_in_words(); | |
1404 const size_t space_capacity = space->capacity_in_words(); | |
1405 | |
1406 const double density = double(space_live) / double(space_capacity); | |
1407 const size_t min_percent_free = | |
1408 id == perm_space_id ? PermMarkSweepDeadRatio : MarkSweepDeadRatio; | |
1409 const double limiter = dead_wood_limiter(density, min_percent_free); | |
1410 const size_t dead_wood_max = space_used - space_live; | |
1411 const size_t dead_wood_limit = MIN2(size_t(space_capacity * limiter), | |
1412 dead_wood_max); | |
1413 | |
1414 if (TraceParallelOldGCDensePrefix) { | |
1415 tty->print_cr("space_live=" SIZE_FORMAT " " "space_used=" SIZE_FORMAT " " | |
1416 "space_cap=" SIZE_FORMAT, | |
1417 space_live, space_used, | |
1418 space_capacity); | |
1419 tty->print_cr("dead_wood_limiter(%6.4f, %d)=%6.4f " | |
1420 "dead_wood_max=" SIZE_FORMAT " dead_wood_limit=" SIZE_FORMAT, | |
1421 density, min_percent_free, limiter, | |
1422 dead_wood_max, dead_wood_limit); | |
1423 } | |
1424 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1425 // Locate the region with the desired amount of dead space to the left. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1426 const RegionData* const limit_cp = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1427 dead_wood_limit_region(full_cp, top_cp, dead_wood_limit); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1428 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1429 // Scan from the first region with dead space to the limit region and find the |
0 | 1430 // one with the best (largest) reclaimed ratio. |
1431 double best_ratio = 0.0; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1432 const RegionData* best_cp = full_cp; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1433 for (const RegionData* cp = full_cp; cp < limit_cp; ++cp) { |
0 | 1434 double tmp_ratio = reclaimed_ratio(cp, bottom, top, new_top); |
1435 if (tmp_ratio > best_ratio) { | |
1436 best_cp = cp; | |
1437 best_ratio = tmp_ratio; | |
1438 } | |
1439 } | |
1440 | |
1441 #if 0 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1442 // Something to consider: if the region with the best ratio is 'close to' the |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1443 // first region w/free space, choose the first region with free space |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1444 // ("first-free"). The first-free region is usually near the start of the |
0 | 1445 // heap, which means we are copying most of the heap already, so copy a bit |
1446 // more to get complete compaction. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1447 if (pointer_delta(best_cp, full_cp, sizeof(RegionData)) < 4) { |
0 | 1448 _maximum_compaction_gc_num = total_invocations(); |
1449 best_cp = full_cp; | |
1450 } | |
1451 #endif // #if 0 | |
1452 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1453 return sd.region_to_addr(best_cp); |
0 | 1454 } |
1455 | |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1456 #ifndef PRODUCT |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1457 void |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1458 PSParallelCompact::fill_with_live_objects(SpaceId id, HeapWord* const start, |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1459 size_t words) |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1460 { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1461 if (TraceParallelOldGCSummaryPhase) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1462 tty->print_cr("fill_with_live_objects [" PTR_FORMAT " " PTR_FORMAT ") " |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1463 SIZE_FORMAT, start, start + words, words); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1464 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1465 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1466 ObjectStartArray* const start_array = _space_info[id].start_array(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1467 CollectedHeap::fill_with_objects(start, words); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1468 for (HeapWord* p = start; p < start + words; p += oop(p)->size()) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1469 _mark_bitmap.mark_obj(p, words); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1470 _summary_data.add_obj(p, words); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1471 start_array->allocate_block(p); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1472 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1473 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1474 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1475 void |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1476 PSParallelCompact::summarize_new_objects(SpaceId id, HeapWord* start) |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1477 { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1478 ParallelCompactData& sd = summary_data(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1479 MutableSpace* space = _space_info[id].space(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1480 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1481 // Find the source and destination start addresses. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1482 HeapWord* const src_addr = sd.region_align_down(start); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1483 HeapWord* dst_addr; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1484 if (src_addr < start) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1485 dst_addr = sd.addr_to_region_ptr(src_addr)->destination(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1486 } else if (src_addr > space->bottom()) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1487 // The start (the original top() value) is aligned to a region boundary so |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1488 // the associated region does not have a destination. Compute the |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1489 // destination from the previous region. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1490 RegionData* const cp = sd.addr_to_region_ptr(src_addr) - 1; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1491 dst_addr = cp->destination() + cp->data_size(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1492 } else { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1493 // Filling the entire space. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1494 dst_addr = space->bottom(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1495 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1496 assert(dst_addr != NULL, "sanity"); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1497 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1498 // Update the summary data. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1499 bool result = _summary_data.summarize(_space_info[id].split_info(), |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1500 src_addr, space->top(), NULL, |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1501 dst_addr, space->end(), |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1502 _space_info[id].new_top_addr()); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1503 assert(result, "should not fail: bad filler object size"); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1504 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1505 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1506 void |
496
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1507 PSParallelCompact::provoke_split_fill_survivor(SpaceId id) |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1508 { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1509 if (total_invocations() % (ParallelOldGCSplitInterval * 3) != 0) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1510 return; |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1511 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1512 |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1513 MutableSpace* const space = _space_info[id].space(); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1514 if (space->is_empty()) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1515 HeapWord* b = space->bottom(); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1516 HeapWord* t = b + space->capacity_in_words() / 2; |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1517 space->set_top(t); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1518 if (ZapUnusedHeapArea) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1519 space->set_top_for_allocations(); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1520 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1521 |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1489
diff
changeset
|
1522 size_t min_size = CollectedHeap::min_fill_size(); |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1489
diff
changeset
|
1523 size_t obj_len = min_size; |
496
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1524 while (b + obj_len <= t) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1525 CollectedHeap::fill_with_object(b, obj_len); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1526 mark_bitmap()->mark_obj(b, obj_len); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1527 summary_data().add_obj(b, obj_len); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1528 b += obj_len; |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1489
diff
changeset
|
1529 obj_len = (obj_len & (min_size*3)) + min_size; // 8 16 24 32 8 16 24 32 ... |
496
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1530 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1531 if (b < t) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1532 // The loop didn't completely fill to t (top); adjust top downward. |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1533 space->set_top(b); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1534 if (ZapUnusedHeapArea) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1535 space->set_top_for_allocations(); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1536 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1537 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1538 |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1539 HeapWord** nta = _space_info[id].new_top_addr(); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1540 bool result = summary_data().summarize(_space_info[id].split_info(), |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1541 space->bottom(), space->top(), NULL, |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1542 space->bottom(), space->end(), nta); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1543 assert(result, "space must fit into itself"); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1544 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1545 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1546 |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1547 void |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1548 PSParallelCompact::provoke_split(bool & max_compaction) |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1549 { |
496
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1550 if (total_invocations() % ParallelOldGCSplitInterval != 0) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1551 return; |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1552 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1553 |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1554 const size_t region_size = ParallelCompactData::RegionSize; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1555 ParallelCompactData& sd = summary_data(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1556 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1557 MutableSpace* const eden_space = _space_info[eden_space_id].space(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1558 MutableSpace* const from_space = _space_info[from_space_id].space(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1559 const size_t eden_live = pointer_delta(eden_space->top(), |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1560 _space_info[eden_space_id].new_top()); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1561 const size_t from_live = pointer_delta(from_space->top(), |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1562 _space_info[from_space_id].new_top()); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1563 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1564 const size_t min_fill_size = CollectedHeap::min_fill_size(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1565 const size_t eden_free = pointer_delta(eden_space->end(), eden_space->top()); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1566 const size_t eden_fillable = eden_free >= min_fill_size ? eden_free : 0; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1567 const size_t from_free = pointer_delta(from_space->end(), from_space->top()); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1568 const size_t from_fillable = from_free >= min_fill_size ? from_free : 0; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1569 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1570 // Choose the space to split; need at least 2 regions live (or fillable). |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1571 SpaceId id; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1572 MutableSpace* space; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1573 size_t live_words; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1574 size_t fill_words; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1575 if (eden_live + eden_fillable >= region_size * 2) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1576 id = eden_space_id; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1577 space = eden_space; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1578 live_words = eden_live; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1579 fill_words = eden_fillable; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1580 } else if (from_live + from_fillable >= region_size * 2) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1581 id = from_space_id; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1582 space = from_space; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1583 live_words = from_live; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1584 fill_words = from_fillable; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1585 } else { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1586 return; // Give up. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1587 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1588 assert(fill_words == 0 || fill_words >= min_fill_size, "sanity"); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1589 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1590 if (live_words < region_size * 2) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1591 // Fill from top() to end() w/live objects of mixed sizes. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1592 HeapWord* const fill_start = space->top(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1593 live_words += fill_words; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1594 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1595 space->set_top(fill_start + fill_words); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1596 if (ZapUnusedHeapArea) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1597 space->set_top_for_allocations(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1598 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1599 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1600 HeapWord* cur_addr = fill_start; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1601 while (fill_words > 0) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1602 const size_t r = (size_t)os::random() % (region_size / 2) + min_fill_size; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1603 size_t cur_size = MIN2(align_object_size_(r), fill_words); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1604 if (fill_words - cur_size < min_fill_size) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1605 cur_size = fill_words; // Avoid leaving a fragment too small to fill. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1606 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1607 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1608 CollectedHeap::fill_with_object(cur_addr, cur_size); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1609 mark_bitmap()->mark_obj(cur_addr, cur_size); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1610 sd.add_obj(cur_addr, cur_size); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1611 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1612 cur_addr += cur_size; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1613 fill_words -= cur_size; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1614 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1615 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1616 summarize_new_objects(id, fill_start); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1617 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1618 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1619 max_compaction = false; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1620 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1621 // Manipulate the old gen so that it has room for about half of the live data |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1622 // in the target young gen space (live_words / 2). |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1623 id = old_space_id; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1624 space = _space_info[id].space(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1625 const size_t free_at_end = space->free_in_words(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1626 const size_t free_target = align_object_size(live_words / 2); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1627 const size_t dead = pointer_delta(space->top(), _space_info[id].new_top()); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1628 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1629 if (free_at_end >= free_target + min_fill_size) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1630 // Fill space above top() and set the dense prefix so everything survives. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1631 HeapWord* const fill_start = space->top(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1632 const size_t fill_size = free_at_end - free_target; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1633 space->set_top(space->top() + fill_size); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1634 if (ZapUnusedHeapArea) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1635 space->set_top_for_allocations(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1636 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1637 fill_with_live_objects(id, fill_start, fill_size); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1638 summarize_new_objects(id, fill_start); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1639 _space_info[id].set_dense_prefix(sd.region_align_down(space->top())); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1640 } else if (dead + free_at_end > free_target) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1641 // Find a dense prefix that makes the right amount of space available. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1642 HeapWord* cur = sd.region_align_down(space->top()); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1643 HeapWord* cur_destination = sd.addr_to_region_ptr(cur)->destination(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1644 size_t dead_to_right = pointer_delta(space->end(), cur_destination); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1645 while (dead_to_right < free_target) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1646 cur -= region_size; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1647 cur_destination = sd.addr_to_region_ptr(cur)->destination(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1648 dead_to_right = pointer_delta(space->end(), cur_destination); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1649 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1650 _space_info[id].set_dense_prefix(cur); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1651 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1652 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1653 #endif // #ifndef PRODUCT |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1654 |
0 | 1655 void PSParallelCompact::summarize_spaces_quick() |
1656 { | |
1657 for (unsigned int i = 0; i < last_space_id; ++i) { | |
1658 const MutableSpace* space = _space_info[i].space(); | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1659 HeapWord** nta = _space_info[i].new_top_addr(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1660 bool result = _summary_data.summarize(_space_info[i].split_info(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1661 space->bottom(), space->top(), NULL, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1662 space->bottom(), space->end(), nta); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1663 assert(result, "space must fit into itself"); |
0 | 1664 _space_info[i].set_dense_prefix(space->bottom()); |
1665 } | |
496
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1666 |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1667 #ifndef PRODUCT |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1668 if (ParallelOldGCSplitALot) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1669 provoke_split_fill_survivor(to_space_id); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1670 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1671 #endif // #ifndef PRODUCT |
0 | 1672 } |
1673 | |
1674 void PSParallelCompact::fill_dense_prefix_end(SpaceId id) | |
1675 { | |
1676 HeapWord* const dense_prefix_end = dense_prefix(id); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1677 const RegionData* region = _summary_data.addr_to_region_ptr(dense_prefix_end); |
0 | 1678 const idx_t dense_prefix_bit = _mark_bitmap.addr_to_bit(dense_prefix_end); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1679 if (dead_space_crosses_boundary(region, dense_prefix_bit)) { |
0 | 1680 // Only enough dead space is filled so that any remaining dead space to the |
1681 // left is larger than the minimum filler object. (The remainder is filled | |
1682 // during the copy/update phase.) | |
1683 // | |
1684 // The size of the dead space to the right of the boundary is not a | |
1685 // concern, since compaction will be able to use whatever space is | |
1686 // available. | |
1687 // | |
1688 // Here '||' is the boundary, 'x' represents a don't care bit and a box | |
1689 // surrounds the space to be filled with an object. | |
1690 // | |
1691 // In the 32-bit VM, each bit represents two 32-bit words: | |
1692 // +---+ | |
1693 // a) beg_bits: ... x x x | 0 | || 0 x x ... | |
1694 // end_bits: ... x x x | 0 | || 0 x x ... | |
1695 // +---+ | |
1696 // | |
1697 // In the 64-bit VM, each bit represents one 64-bit word: | |
1698 // +------------+ | |
1699 // b) beg_bits: ... x x x | 0 || 0 | x x ... | |
1700 // end_bits: ... x x 1 | 0 || 0 | x x ... | |
1701 // +------------+ | |
1702 // +-------+ | |
1703 // c) beg_bits: ... x x | 0 0 | || 0 x x ... | |
1704 // end_bits: ... x 1 | 0 0 | || 0 x x ... | |
1705 // +-------+ | |
1706 // +-----------+ | |
1707 // d) beg_bits: ... x | 0 0 0 | || 0 x x ... | |
1708 // end_bits: ... 1 | 0 0 0 | || 0 x x ... | |
1709 // +-----------+ | |
1710 // +-------+ | |
1711 // e) beg_bits: ... 0 0 | 0 0 | || 0 x x ... | |
1712 // end_bits: ... 0 0 | 0 0 | || 0 x x ... | |
1713 // +-------+ | |
1714 | |
1715 // Initially assume case a, c or e will apply. | |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1489
diff
changeset
|
1716 size_t obj_len = CollectedHeap::min_fill_size(); |
0 | 1717 HeapWord* obj_beg = dense_prefix_end - obj_len; |
1718 | |
1719 #ifdef _LP64 | |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1489
diff
changeset
|
1720 if (MinObjAlignment > 1) { // object alignment > heap word size |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1489
diff
changeset
|
1721 // Cases a, c or e. |
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1489
diff
changeset
|
1722 } else if (_mark_bitmap.is_obj_end(dense_prefix_bit - 2)) { |
0 | 1723 // Case b above. |
1724 obj_beg = dense_prefix_end - 1; | |
1725 } else if (!_mark_bitmap.is_obj_end(dense_prefix_bit - 3) && | |
1726 _mark_bitmap.is_obj_end(dense_prefix_bit - 4)) { | |
1727 // Case d above. | |
1728 obj_beg = dense_prefix_end - 3; | |
1729 obj_len = 3; | |
1730 } | |
1731 #endif // #ifdef _LP64 | |
1732 | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1733 CollectedHeap::fill_with_object(obj_beg, obj_len); |
0 | 1734 _mark_bitmap.mark_obj(obj_beg, obj_len); |
1735 _summary_data.add_obj(obj_beg, obj_len); | |
1736 assert(start_array(id) != NULL, "sanity"); | |
1737 start_array(id)->allocate_block(obj_beg); | |
1738 } | |
1739 } | |
1740 | |
1741 void | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1742 PSParallelCompact::clear_source_region(HeapWord* beg_addr, HeapWord* end_addr) |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1743 { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1744 RegionData* const beg_ptr = _summary_data.addr_to_region_ptr(beg_addr); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1745 HeapWord* const end_aligned_up = _summary_data.region_align_up(end_addr); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1746 RegionData* const end_ptr = _summary_data.addr_to_region_ptr(end_aligned_up); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1747 for (RegionData* cur = beg_ptr; cur < end_ptr; ++cur) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1748 cur->set_source_region(0); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1749 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1750 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1751 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1752 void |
0 | 1753 PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction) |
1754 { | |
1755 assert(id < last_space_id, "id out of range"); | |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1756 assert(_space_info[id].dense_prefix() == _space_info[id].space()->bottom() || |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1757 ParallelOldGCSplitALot && id == old_space_id, |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1758 "should have been reset in summarize_spaces_quick()"); |
0 | 1759 |
1760 const MutableSpace* space = _space_info[id].space(); | |
265
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1761 if (_space_info[id].new_top() != space->bottom()) { |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1762 HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction); |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1763 _space_info[id].set_dense_prefix(dense_prefix_end); |
0 | 1764 |
1765 #ifndef PRODUCT | |
265
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1766 if (TraceParallelOldGCDensePrefix) { |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1767 print_dense_prefix_stats("ratio", id, maximum_compaction, |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1768 dense_prefix_end); |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1769 HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction); |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1770 print_dense_prefix_stats("density", id, maximum_compaction, addr); |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1771 } |
0 | 1772 #endif // #ifndef PRODUCT |
1773 | |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1774 // Recompute the summary data, taking into account the dense prefix. If |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1775 // every last byte will be reclaimed, then the existing summary data which |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1776 // compacts everything can be left in place. |
265
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1777 if (!maximum_compaction && dense_prefix_end != space->bottom()) { |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1778 // If dead space crosses the dense prefix boundary, it is (at least |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1779 // partially) filled with a dummy object, marked live and added to the |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1780 // summary data. This simplifies the copy/update phase and must be done |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1781 // before the final locations of objects are determined, to prevent |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1782 // leaving a fragment of dead space that is too small to fill. |
265
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1783 fill_dense_prefix_end(id); |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1784 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1785 // Compute the destination of each Region, and thus each object. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1786 _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1787 _summary_data.summarize(_space_info[id].split_info(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1788 dense_prefix_end, space->top(), NULL, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1789 dense_prefix_end, space->end(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1790 _space_info[id].new_top_addr()); |
265
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1791 } |
0 | 1792 } |
1793 | |
1794 if (TraceParallelOldGCSummaryPhase) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1795 const size_t region_size = ParallelCompactData::RegionSize; |
265
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1796 HeapWord* const dense_prefix_end = _space_info[id].dense_prefix(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1797 const size_t dp_region = _summary_data.addr_to_region_idx(dense_prefix_end); |
0 | 1798 const size_t dp_words = pointer_delta(dense_prefix_end, space->bottom()); |
265
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1799 HeapWord* const new_top = _space_info[id].new_top(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1800 const HeapWord* nt_aligned_up = _summary_data.region_align_up(new_top); |
0 | 1801 const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end); |
1802 tty->print_cr("id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " " | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1803 "dp_region=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " " |
0 | 1804 "cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT, |
1805 id, space->capacity_in_words(), dense_prefix_end, | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1806 dp_region, dp_words / region_size, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1807 cr_words / region_size, new_top); |
0 | 1808 } |
1809 } | |
1810 | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1811 #ifndef PRODUCT |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1812 void PSParallelCompact::summary_phase_msg(SpaceId dst_space_id, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1813 HeapWord* dst_beg, HeapWord* dst_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1814 SpaceId src_space_id, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1815 HeapWord* src_beg, HeapWord* src_end) |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1816 { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1817 if (TraceParallelOldGCSummaryPhase) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1818 tty->print_cr("summarizing %d [%s] into %d [%s]: " |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1819 "src=" PTR_FORMAT "-" PTR_FORMAT " " |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1820 SIZE_FORMAT "-" SIZE_FORMAT " " |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1821 "dst=" PTR_FORMAT "-" PTR_FORMAT " " |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1822 SIZE_FORMAT "-" SIZE_FORMAT, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1823 src_space_id, space_names[src_space_id], |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1824 dst_space_id, space_names[dst_space_id], |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1825 src_beg, src_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1826 _summary_data.addr_to_region_idx(src_beg), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1827 _summary_data.addr_to_region_idx(src_end), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1828 dst_beg, dst_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1829 _summary_data.addr_to_region_idx(dst_beg), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1830 _summary_data.addr_to_region_idx(dst_end)); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1831 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1832 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1833 #endif // #ifndef PRODUCT |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1834 |
0 | 1835 void PSParallelCompact::summary_phase(ParCompactionManager* cm, |
1836 bool maximum_compaction) | |
1837 { | |
1838 EventMark m("2 summarize"); | |
1839 TraceTime tm("summary phase", print_phases(), true, gclog_or_tty); | |
1840 // trace("2"); | |
1841 | |
1842 #ifdef ASSERT | |
1843 if (TraceParallelOldGCMarkingPhase) { | |
1844 tty->print_cr("add_obj_count=" SIZE_FORMAT " " | |
1845 "add_obj_bytes=" SIZE_FORMAT, | |
1846 add_obj_count, add_obj_size * HeapWordSize); | |
1847 tty->print_cr("mark_bitmap_count=" SIZE_FORMAT " " | |
1848 "mark_bitmap_bytes=" SIZE_FORMAT, | |
1849 mark_bitmap_count, mark_bitmap_size * HeapWordSize); | |
1850 } | |
1851 #endif // #ifdef ASSERT | |
1852 | |
1853 // Quick summarization of each space into itself, to see how much is live. | |
1854 summarize_spaces_quick(); | |
1855 | |
1856 if (TraceParallelOldGCSummaryPhase) { | |
1857 tty->print_cr("summary_phase: after summarizing each space to self"); | |
1858 Universe::print(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1859 NOT_PRODUCT(print_region_ranges()); |
0 | 1860 if (Verbose) { |
1861 NOT_PRODUCT(print_initial_summary_data(_summary_data, _space_info)); | |
1862 } | |
1863 } | |
1864 | |
1865 // The amount of live data that will end up in old space (assuming it fits). | |
1866 size_t old_space_total_live = 0; | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1867 assert(perm_space_id < old_space_id, "should not count perm data here"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1868 for (unsigned int id = old_space_id; id < last_space_id; ++id) { |
0 | 1869 old_space_total_live += pointer_delta(_space_info[id].new_top(), |
1870 _space_info[id].space()->bottom()); | |
1871 } | |
1872 | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1873 MutableSpace* const old_space = _space_info[old_space_id].space(); |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1874 const size_t old_capacity = old_space->capacity_in_words(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1875 if (old_space_total_live > old_capacity) { |
0 | 1876 // XXX - should also try to expand |
1877 maximum_compaction = true; | |
1878 } | |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1879 #ifndef PRODUCT |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1880 if (ParallelOldGCSplitALot && old_space_total_live < old_capacity) { |
496
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1881 provoke_split(maximum_compaction); |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1882 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1883 #endif // #ifndef PRODUCT |
0 | 1884 |
1885 // Permanent and Old generations. | |
1886 summarize_space(perm_space_id, maximum_compaction); | |
1887 summarize_space(old_space_id, maximum_compaction); | |
1888 | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1889 // Summarize the remaining spaces in the young gen. The initial target space |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1890 // is the old gen. If a space does not fit entirely into the target, then the |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1891 // remainder is compacted into the space itself and that space becomes the new |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1892 // target. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1893 SpaceId dst_space_id = old_space_id; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1894 HeapWord* dst_space_end = old_space->end(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1895 HeapWord** new_top_addr = _space_info[dst_space_id].new_top_addr(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1896 for (unsigned int id = eden_space_id; id < last_space_id; ++id) { |
0 | 1897 const MutableSpace* space = _space_info[id].space(); |
1898 const size_t live = pointer_delta(_space_info[id].new_top(), | |
1899 space->bottom()); | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1900 const size_t available = pointer_delta(dst_space_end, *new_top_addr); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1901 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1902 NOT_PRODUCT(summary_phase_msg(dst_space_id, *new_top_addr, dst_space_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1903 SpaceId(id), space->bottom(), space->top());) |
266
2214b226b7f0
6724367: par compact could clear less young gen summary data
jcoomes
parents:
265
diff
changeset
|
1904 if (live > 0 && live <= available) { |
0 | 1905 // All the live data will fit. |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1906 bool done = _summary_data.summarize(_space_info[id].split_info(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1907 space->bottom(), space->top(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1908 NULL, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1909 *new_top_addr, dst_space_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1910 new_top_addr); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1911 assert(done, "space must fit into old gen"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1912 |
266
2214b226b7f0
6724367: par compact could clear less young gen summary data
jcoomes
parents:
265
diff
changeset
|
1913 // Reset the new_top value for the space. |
2214b226b7f0
6724367: par compact could clear less young gen summary data
jcoomes
parents:
265
diff
changeset
|
1914 _space_info[id].set_new_top(space->bottom()); |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1915 } else if (live > 0) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1916 // Attempt to fit part of the source space into the target space. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1917 HeapWord* next_src_addr = NULL; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1918 bool done = _summary_data.summarize(_space_info[id].split_info(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1919 space->bottom(), space->top(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1920 &next_src_addr, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1921 *new_top_addr, dst_space_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1922 new_top_addr); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1923 assert(!done, "space should not fit into old gen"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1924 assert(next_src_addr != NULL, "sanity"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1925 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1926 // The source space becomes the new target, so the remainder is compacted |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1927 // within the space itself. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1928 dst_space_id = SpaceId(id); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1929 dst_space_end = space->end(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1930 new_top_addr = _space_info[id].new_top_addr(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1931 NOT_PRODUCT(summary_phase_msg(dst_space_id, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1932 space->bottom(), dst_space_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1933 SpaceId(id), next_src_addr, space->top());) |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1934 done = _summary_data.summarize(_space_info[id].split_info(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1935 next_src_addr, space->top(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1936 NULL, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1937 space->bottom(), dst_space_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1938 new_top_addr); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1939 assert(done, "space must fit when compacted into itself"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1940 assert(*new_top_addr <= space->top(), "usage should not grow"); |
0 | 1941 } |
1942 } | |
1943 | |
1944 if (TraceParallelOldGCSummaryPhase) { | |
1945 tty->print_cr("summary_phase: after final summarization"); | |
1946 Universe::print(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1947 NOT_PRODUCT(print_region_ranges()); |
0 | 1948 if (Verbose) { |
1949 NOT_PRODUCT(print_generic_summary_data(_summary_data, _space_info)); | |
1950 } | |
1951 } | |
1952 } | |
1953 | |
1954 // This method should contain all heap-specific policy for invoking a full | |
1955 // collection. invoke_no_policy() will only attempt to compact the heap; it | |
1956 // will do nothing further. If we need to bail out for policy reasons, scavenge | |
1957 // before full gc, or any other specialized behavior, it needs to be added here. | |
1958 // | |
1959 // Note that this method should only be called from the vm_thread while at a | |
1960 // safepoint. | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1961 // |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1962 // Note that the all_soft_refs_clear flag in the collector policy |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1963 // may be true because this method can be called without intervening |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1964 // activity. For example when the heap space is tight and full measure |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1965 // are being taken to free space. |
0 | 1966 void PSParallelCompact::invoke(bool maximum_heap_compaction) { |
1967 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); | |
1968 assert(Thread::current() == (Thread*)VMThread::vm_thread(), | |
1969 "should be in vm thread"); | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1970 |
0 | 1971 ParallelScavengeHeap* heap = gc_heap(); |
1972 GCCause::Cause gc_cause = heap->gc_cause(); | |
1973 assert(!heap->is_gc_active(), "not reentrant"); | |
1974 | |
1975 PSAdaptiveSizePolicy* policy = heap->size_policy(); | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1976 IsGCActiveMark mark; |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1977 |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1978 if (ScavengeBeforeFullGC) { |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1979 PSScavenge::invoke_no_policy(); |
0 | 1980 } |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1981 |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1982 const bool clear_all_soft_refs = |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1983 heap->collector_policy()->should_clear_all_soft_refs(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1984 |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1985 PSParallelCompact::invoke_no_policy(clear_all_soft_refs || |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1986 maximum_heap_compaction); |
0 | 1987 } |
1988 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1989 bool ParallelCompactData::region_contains(size_t region_index, HeapWord* addr) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1990 size_t addr_region_index = addr_to_region_idx(addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1991 return region_index == addr_region_index; |
0 | 1992 } |
1993 | |
1994 // This method contains no policy. You should probably | |
1995 // be calling invoke() instead. | |
1996 void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { | |
1997 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); | |
1998 assert(ref_processor() != NULL, "Sanity"); | |
1999 | |
139
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
0
diff
changeset
|
2000 if (GC_locker::check_active_before_gc()) { |
0 | 2001 return; |
2002 } | |
2003 | |
2004 TimeStamp marking_start; | |
2005 TimeStamp compaction_start; | |
2006 TimeStamp collection_exit; | |
2007 | |
2008 ParallelScavengeHeap* heap = gc_heap(); | |
2009 GCCause::Cause gc_cause = heap->gc_cause(); | |
2010 PSYoungGen* young_gen = heap->young_gen(); | |
2011 PSOldGen* old_gen = heap->old_gen(); | |
2012 PSPermGen* perm_gen = heap->perm_gen(); | |
2013 PSAdaptiveSizePolicy* size_policy = heap->size_policy(); | |
2014 | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
2015 // The scope of casr should end after code that can change |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
2016 // CollectorPolicy::_should_clear_all_soft_refs. |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
2017 ClearedAllSoftRefs casr(maximum_heap_compaction, |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
2018 heap->collector_policy()); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
2019 |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2020 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2021 // Save information needed to minimize mangling |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2022 heap->record_gen_tops_before_GC(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2023 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2024 |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
2025 heap->pre_full_gc_dump(); |
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
2026 |
0 | 2027 _print_phases = PrintGCDetails && PrintParallelOldGCPhaseTimes; |
2028 | |
2029 // Make sure data structures are sane, make the heap parsable, and do other | |
2030 // miscellaneous bookkeeping. | |
2031 PreGCValues pre_gc_values; | |
2032 pre_compact(&pre_gc_values); | |
2033 | |
210 | 2034 // Get the compaction manager reserved for the VM thread. |
2035 ParCompactionManager* const vmthread_cm = | |
2036 ParCompactionManager::manager_array(gc_task_manager()->workers()); | |
2037 | |
0 | 2038 // Place after pre_compact() where the number of invocations is incremented. |
2039 AdaptiveSizePolicyOutput(size_policy, heap->total_collections()); | |
2040 | |
2041 { | |
2042 ResourceMark rm; | |
2043 HandleMark hm; | |
2044 | |
2045 const bool is_system_gc = gc_cause == GCCause::_java_lang_system_gc; | |
2046 | |
2047 // This is useful for debugging but don't change the output the | |
2048 // the customer sees. | |
2049 const char* gc_cause_str = "Full GC"; | |
2050 if (is_system_gc && PrintGCDetails) { | |
2051 gc_cause_str = "Full GC (System)"; | |
2052 } | |
2053 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); | |
2054 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); | |
2055 TraceTime t1(gc_cause_str, PrintGC, !PrintGCDetails, gclog_or_tty); | |
2056 TraceCollectorStats tcs(counters()); | |
2057 TraceMemoryManagerStats tms(true /* Full GC */); | |
2058 | |
2059 if (TraceGen1Time) accumulated_time()->start(); | |
2060 | |
2061 // Let the size policy know we're starting | |
2062 size_policy->major_collection_begin(); | |
2063 | |
2064 // When collecting the permanent generation methodOops may be moving, | |
2065 // so we either have to flush all bcp data or convert it into bci. | |
2066 CodeCache::gc_prologue(); | |
2067 Threads::gc_prologue(); | |
2068 | |
2069 NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); | |
2070 COMPILER2_PRESENT(DerivedPointerTable::clear()); | |
2071 | |
2072 ref_processor()->enable_discovery(); | |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
2073 ref_processor()->setup_policy(maximum_heap_compaction); |
0 | 2074 |
2075 bool marked_for_unloading = false; | |
2076 | |
2077 marking_start.update(); | |
210 | 2078 marking_phase(vmthread_cm, maximum_heap_compaction); |
0 | 2079 |
2080 #ifndef PRODUCT | |
2081 if (TraceParallelOldGCMarkingPhase) { | |
2082 gclog_or_tty->print_cr("marking_phase: cas_tries %d cas_retries %d " | |
2083 "cas_by_another %d", | |
2084 mark_bitmap()->cas_tries(), mark_bitmap()->cas_retries(), | |
2085 mark_bitmap()->cas_by_another()); | |
2086 } | |
2087 #endif // #ifndef PRODUCT | |
2088 | |
2089 bool max_on_system_gc = UseMaximumCompactionOnSystemGC && is_system_gc; | |
210 | 2090 summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc); |
0 | 2091 |
2092 COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity")); | |
2093 COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); | |
2094 | |
2095 // adjust_roots() updates Universe::_intArrayKlassObj which is | |
2096 // needed by the compaction for filling holes in the dense prefix. | |
2097 adjust_roots(); | |
2098 | |
2099 compaction_start.update(); | |
2100 // Does the perm gen always have to be done serially because | |
2101 // klasses are used in the update of an object? | |
210 | 2102 compact_perm(vmthread_cm); |
0 | 2103 |
2104 if (UseParallelOldGCCompacting) { | |
2105 compact(); | |
2106 } else { | |
210 | 2107 compact_serial(vmthread_cm); |
0 | 2108 } |
2109 | |
2110 // Reset the mark bitmap, summary data, and do other bookkeeping. Must be | |
2111 // done before resizing. | |
2112 post_compact(); | |
2113 | |
2114 // Let the size policy know we're done | |
2115 size_policy->major_collection_end(old_gen->used_in_bytes(), gc_cause); | |
2116 | |
2117 if (UseAdaptiveSizePolicy) { | |
2118 if (PrintAdaptiveSizePolicy) { | |
2119 gclog_or_tty->print("AdaptiveSizeStart: "); | |
2120 gclog_or_tty->stamp(); | |
2121 gclog_or_tty->print_cr(" collection: %d ", | |
2122 heap->total_collections()); | |
2123 if (Verbose) { | |
2124 gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d" | |
2125 " perm_gen_capacity: %d ", | |
2126 old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes(), | |
2127 perm_gen->capacity_in_bytes()); | |
2128 } | |
2129 } | |
2130 | |
2131 // Don't check if the size_policy is ready here. Let | |
2132 // the size_policy check that internally. | |
2133 if (UseAdaptiveGenerationSizePolicyAtMajorCollection && | |
2134 ((gc_cause != GCCause::_java_lang_system_gc) || | |
2135 UseAdaptiveSizePolicyWithSystemGC)) { | |
2136 // Calculate optimal free space amounts | |
2137 assert(young_gen->max_size() > | |
2138 young_gen->from_space()->capacity_in_bytes() + | |
2139 young_gen->to_space()->capacity_in_bytes(), | |
2140 "Sizes of space in young gen are out-of-bounds"); | |
2141 size_t max_eden_size = young_gen->max_size() - | |
2142 young_gen->from_space()->capacity_in_bytes() - | |
2143 young_gen->to_space()->capacity_in_bytes(); | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2144 size_policy->compute_generation_free_space( |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2145 young_gen->used_in_bytes(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2146 young_gen->eden_space()->used_in_bytes(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2147 old_gen->used_in_bytes(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2148 perm_gen->used_in_bytes(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2149 young_gen->eden_space()->capacity_in_bytes(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2150 old_gen->max_gen_size(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2151 max_eden_size, |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2152 true /* full gc*/, |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
2153 gc_cause, |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
2154 heap->collector_policy()); |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2155 |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2156 heap->resize_old_gen( |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2157 size_policy->calculated_old_free_size_in_bytes()); |
0 | 2158 |
2159 // Don't resize the young generation at an major collection. A | |
2160 // desired young generation size may have been calculated but | |
2161 // resizing the young generation complicates the code because the | |
2162 // resizing of the old generation may have moved the boundary | |
2163 // between the young generation and the old generation. Let the | |
2164 // young generation resizing happen at the minor collections. | |
2165 } | |
2166 if (PrintAdaptiveSizePolicy) { | |
2167 gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ", | |
2168 heap->total_collections()); | |
2169 } | |
2170 } | |
2171 | |
2172 if (UsePerfData) { | |
2173 PSGCAdaptivePolicyCounters* const counters = heap->gc_policy_counters(); | |
2174 counters->update_counters(); | |
2175 counters->update_old_capacity(old_gen->capacity_in_bytes()); | |
2176 counters->update_young_capacity(young_gen->capacity_in_bytes()); | |
2177 } | |
2178 | |
2179 heap->resize_all_tlabs(); | |
2180 | |
2181 // We collected the perm gen, so we'll resize it here. | |
2182 perm_gen->compute_new_size(pre_gc_values.perm_gen_used()); | |
2183 | |
2184 if (TraceGen1Time) accumulated_time()->stop(); | |
2185 | |
2186 if (PrintGC) { | |
2187 if (PrintGCDetails) { | |
2188 // No GC timestamp here. This is after GC so it would be confusing. | |
2189 young_gen->print_used_change(pre_gc_values.young_gen_used()); | |
2190 old_gen->print_used_change(pre_gc_values.old_gen_used()); | |
2191 heap->print_heap_change(pre_gc_values.heap_used()); | |
2192 // Print perm gen last (print_heap_change() excludes the perm gen). | |
2193 perm_gen->print_used_change(pre_gc_values.perm_gen_used()); | |
2194 } else { | |
2195 heap->print_heap_change(pre_gc_values.heap_used()); | |
2196 } | |
2197 } | |
2198 | |
2199 // Track memory usage and detect low memory | |
2200 MemoryService::track_memory_usage(); | |
2201 heap->update_counters(); | |
2202 } | |
2203 | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2204 #ifdef ASSERT |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2205 for (size_t i = 0; i < ParallelGCThreads + 1; ++i) { |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2206 ParCompactionManager* const cm = |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2207 ParCompactionManager::manager_array(int(i)); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2208 assert(cm->marking_stack()->is_empty(), "should be empty"); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2209 assert(cm->region_stack()->is_empty(), "should be empty"); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2210 assert(cm->revisit_klass_stack()->is_empty(), "should be empty"); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2211 } |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2212 #endif // ASSERT |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2213 |
0 | 2214 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) { |
2215 HandleMark hm; // Discard invalid handles created during verification | |
2216 gclog_or_tty->print(" VerifyAfterGC:"); | |
2217 Universe::verify(false); | |
2218 } | |
2219 | |
2220 // Re-verify object start arrays | |
2221 if (VerifyObjectStartArray && | |
2222 VerifyAfterGC) { | |
2223 old_gen->verify_object_start_array(); | |
2224 perm_gen->verify_object_start_array(); | |
2225 } | |
2226 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2227 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2228 old_gen->object_space()->check_mangled_unused_area_complete(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2229 perm_gen->object_space()->check_mangled_unused_area_complete(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2230 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2231 |
0 | 2232 NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); |
2233 | |
2234 collection_exit.update(); | |
2235 | |
2236 if (PrintHeapAtGC) { | |
2237 Universe::print_heap_after_gc(); | |
2238 } | |
2239 if (PrintGCTaskTimeStamps) { | |
2240 gclog_or_tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " " | |
2241 INT64_FORMAT, | |
2242 marking_start.ticks(), compaction_start.ticks(), | |
2243 collection_exit.ticks()); | |
2244 gc_task_manager()->print_task_time_stamps(); | |
2245 } | |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
496
diff
changeset
|
2246 |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
2247 heap->post_full_gc_dump(); |
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
2248 |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
496
diff
changeset
|
2249 #ifdef TRACESPINNING |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
496
diff
changeset
|
2250 ParallelTaskTerminator::print_termination_counts(); |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
496
diff
changeset
|
2251 #endif |
0 | 2252 } |
2253 | |
2254 bool PSParallelCompact::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy, | |
2255 PSYoungGen* young_gen, | |
2256 PSOldGen* old_gen) { | |
2257 MutableSpace* const eden_space = young_gen->eden_space(); | |
2258 assert(!eden_space->is_empty(), "eden must be non-empty"); | |
2259 assert(young_gen->virtual_space()->alignment() == | |
2260 old_gen->virtual_space()->alignment(), "alignments do not match"); | |
2261 | |
2262 if (!(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary)) { | |
2263 return false; | |
2264 } | |
2265 | |
2266 // Both generations must be completely committed. | |
2267 if (young_gen->virtual_space()->uncommitted_size() != 0) { | |
2268 return false; | |
2269 } | |
2270 if (old_gen->virtual_space()->uncommitted_size() != 0) { | |
2271 return false; | |
2272 } | |
2273 | |
2274 // Figure out how much to take from eden. Include the average amount promoted | |
2275 // in the total; otherwise the next young gen GC will simply bail out to a | |
2276 // full GC. | |
2277 const size_t alignment = old_gen->virtual_space()->alignment(); | |
2278 const size_t eden_used = eden_space->used_in_bytes(); | |
2279 const size_t promoted = (size_t)size_policy->avg_promoted()->padded_average(); | |
2280 const size_t absorb_size = align_size_up(eden_used + promoted, alignment); | |
2281 const size_t eden_capacity = eden_space->capacity_in_bytes(); | |
2282 | |
2283 if (absorb_size >= eden_capacity) { | |
2284 return false; // Must leave some space in eden. | |
2285 } | |
2286 | |
2287 const size_t new_young_size = young_gen->capacity_in_bytes() - absorb_size; | |
2288 if (new_young_size < young_gen->min_gen_size()) { | |
2289 return false; // Respect young gen minimum size. | |
2290 } | |
2291 | |
2292 if (TraceAdaptiveGCBoundary && Verbose) { | |
2293 gclog_or_tty->print(" absorbing " SIZE_FORMAT "K: " | |
2294 "eden " SIZE_FORMAT "K->" SIZE_FORMAT "K " | |
2295 "from " SIZE_FORMAT "K, to " SIZE_FORMAT "K " | |
2296 "young_gen " SIZE_FORMAT "K->" SIZE_FORMAT "K ", | |
2297 absorb_size / K, | |
2298 eden_capacity / K, (eden_capacity - absorb_size) / K, | |
2299 young_gen->from_space()->used_in_bytes() / K, | |
2300 young_gen->to_space()->used_in_bytes() / K, | |
2301 young_gen->capacity_in_bytes() / K, new_young_size / K); | |
2302 } | |
2303 | |
2304 // Fill the unused part of the old gen. | |
2305 MutableSpace* const old_space = old_gen->object_space(); | |
481
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2306 HeapWord* const unused_start = old_space->top(); |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2307 size_t const unused_words = pointer_delta(old_space->end(), unused_start); |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2308 |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2309 if (unused_words > 0) { |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2310 if (unused_words < CollectedHeap::min_fill_size()) { |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2311 return false; // If the old gen cannot be filled, must give up. |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2312 } |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2313 CollectedHeap::fill_with_objects(unused_start, unused_words); |
0 | 2314 } |
2315 | |
2316 // Take the live data from eden and set both top and end in the old gen to | |
2317 // eden top. (Need to set end because reset_after_change() mangles the region | |
2318 // from end to virtual_space->high() in debug builds). | |
2319 HeapWord* const new_top = eden_space->top(); | |
2320 old_gen->virtual_space()->expand_into(young_gen->virtual_space(), | |
2321 absorb_size); | |
2322 young_gen->reset_after_change(); | |
2323 old_space->set_top(new_top); | |
2324 old_space->set_end(new_top); | |
2325 old_gen->reset_after_change(); | |
2326 | |
2327 // Update the object start array for the filler object and the data from eden. | |
2328 ObjectStartArray* const start_array = old_gen->start_array(); | |
481
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2329 for (HeapWord* p = unused_start; p < new_top; p += oop(p)->size()) { |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2330 start_array->allocate_block(p); |
0 | 2331 } |
2332 | |
2333 // Could update the promoted average here, but it is not typically updated at | |
2334 // full GCs and the value to use is unclear. Something like | |
2335 // | |
2336 // cur_promoted_avg + absorb_size / number_of_scavenges_since_last_full_gc. | |
2337 | |
2338 size_policy->set_bytes_absorbed_from_eden(absorb_size); | |
2339 return true; | |
2340 } | |
2341 | |
2342 GCTaskManager* const PSParallelCompact::gc_task_manager() { | |
2343 assert(ParallelScavengeHeap::gc_task_manager() != NULL, | |
2344 "shouldn't return NULL"); | |
2345 return ParallelScavengeHeap::gc_task_manager(); | |
2346 } | |
2347 | |
2348 void PSParallelCompact::marking_phase(ParCompactionManager* cm, | |
2349 bool maximum_heap_compaction) { | |
2350 // Recursively traverse all live objects and mark them | |
2351 EventMark m("1 mark object"); | |
2352 TraceTime tm("marking phase", print_phases(), true, gclog_or_tty); | |
2353 | |
2354 ParallelScavengeHeap* heap = gc_heap(); | |
2355 uint parallel_gc_threads = heap->gc_task_manager()->workers(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2356 TaskQueueSetSuper* qset = ParCompactionManager::region_array(); |
0 | 2357 ParallelTaskTerminator terminator(parallel_gc_threads, qset); |
2358 | |
2359 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); | |
2360 PSParallelCompact::FollowStackClosure follow_stack_closure(cm); | |
2361 | |
2362 { | |
2363 TraceTime tm_m("par mark", print_phases(), true, gclog_or_tty); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
696
diff
changeset
|
2364 ParallelScavengeHeap::ParStrongRootsScope psrs; |
0 | 2365 |
2366 GCTaskQueue* q = GCTaskQueue::create(); | |
2367 | |
2368 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::universe)); | |
2369 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jni_handles)); | |
2370 // We scan the thread roots in parallel | |
2371 Threads::create_thread_roots_marking_tasks(q); | |
2372 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::object_synchronizer)); | |
2373 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::flat_profiler)); | |
2374 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management)); | |
2375 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary)); | |
2376 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti)); | |
2377 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::vm_symbols)); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
696
diff
changeset
|
2378 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache)); |
0 | 2379 |
2380 if (parallel_gc_threads > 1) { | |
2381 for (uint j = 0; j < parallel_gc_threads; j++) { | |
2382 q->enqueue(new StealMarkingTask(&terminator)); | |
2383 } | |
2384 } | |
2385 | |
2386 WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create(); | |
2387 q->enqueue(fin); | |
2388 | |
2389 gc_task_manager()->add_list(q); | |
2390 | |
2391 fin->wait_for(); | |
2392 | |
2393 // We have to release the barrier tasks! | |
2394 WaitForBarrierGCTask::destroy(fin); | |
2395 } | |
2396 | |
2397 // Process reference objects found during marking | |
2398 { | |
2399 TraceTime tm_r("reference processing", print_phases(), true, gclog_or_tty); | |
2400 if (ref_processor()->processing_is_mt()) { | |
2401 RefProcTaskExecutor task_executor; | |
2402 ref_processor()->process_discovered_references( | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
376
diff
changeset
|
2403 is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
376
diff
changeset
|
2404 &task_executor); |
0 | 2405 } else { |
2406 ref_processor()->process_discovered_references( | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
376
diff
changeset
|
2407 is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL); |
0 | 2408 } |
2409 } | |
2410 | |
2411 TraceTime tm_c("class unloading", print_phases(), true, gclog_or_tty); | |
2412 // Follow system dictionary roots and unload classes. | |
2413 bool purged_class = SystemDictionary::do_unloading(is_alive_closure()); | |
2414 | |
2415 // Follow code cache roots. | |
2416 CodeCache::do_unloading(is_alive_closure(), &mark_and_push_closure, | |
2417 purged_class); | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
997
diff
changeset
|
2418 cm->follow_marking_stacks(); // Flush marking stack. |
0 | 2419 |
2420 // Update subklass/sibling/implementor links of live klasses | |
2421 // revisit_klass_stack is used in follow_weak_klass_links(). | |
941 | 2422 follow_weak_klass_links(); |
2423 | |
2424 // Revisit memoized MDO's and clear any unmarked weak refs | |
2425 follow_mdo_weak_refs(); | |
0 | 2426 |
2427 // Visit symbol and interned string tables and delete unmarked oops | |
2428 SymbolTable::unlink(is_alive_closure()); | |
2429 StringTable::unlink(is_alive_closure()); | |
2430 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
997
diff
changeset
|
2431 assert(cm->marking_stacks_empty(), "marking stacks should be empty"); |
0 | 2432 } |
2433 | |
2434 // This should be moved to the shared markSweep code! | |
2435 class PSAlwaysTrueClosure: public BoolObjectClosure { | |
2436 public: | |
2437 void do_object(oop p) { ShouldNotReachHere(); } | |
2438 bool do_object_b(oop p) { return true; } | |
2439 }; | |
2440 static PSAlwaysTrueClosure always_true; | |
2441 | |
2442 void PSParallelCompact::adjust_roots() { | |
2443 // Adjust the pointers to reflect the new locations | |
2444 EventMark m("3 adjust roots"); | |
2445 TraceTime tm("adjust roots", print_phases(), true, gclog_or_tty); | |
2446 | |
2447 // General strong roots. | |
2448 Universe::oops_do(adjust_root_pointer_closure()); | |
2449 ReferenceProcessor::oops_do(adjust_root_pointer_closure()); | |
2450 JNIHandles::oops_do(adjust_root_pointer_closure()); // Global (strong) JNI handles | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
696
diff
changeset
|
2451 Threads::oops_do(adjust_root_pointer_closure(), NULL); |
0 | 2452 ObjectSynchronizer::oops_do(adjust_root_pointer_closure()); |
2453 FlatProfiler::oops_do(adjust_root_pointer_closure()); | |
2454 Management::oops_do(adjust_root_pointer_closure()); | |
2455 JvmtiExport::oops_do(adjust_root_pointer_closure()); | |
2456 // SO_AllClasses | |
2457 SystemDictionary::oops_do(adjust_root_pointer_closure()); | |
2458 vmSymbols::oops_do(adjust_root_pointer_closure()); | |
2459 | |
2460 // Now adjust pointers in remaining weak roots. (All of which should | |
2461 // have been cleared if they pointed to non-surviving objects.) | |
2462 // Global (weak) JNI handles | |
2463 JNIHandles::weak_oops_do(&always_true, adjust_root_pointer_closure()); | |
2464 | |
2465 CodeCache::oops_do(adjust_pointer_closure()); | |
2466 SymbolTable::oops_do(adjust_root_pointer_closure()); | |
2467 StringTable::oops_do(adjust_root_pointer_closure()); | |
2468 ref_processor()->weak_oops_do(adjust_root_pointer_closure()); | |
2469 // Roots were visited so references into the young gen in roots | |
2470 // may have been scanned. Process them also. | |
2471 // Should the reference processor have a span that excludes | |
2472 // young gen objects? | |
2473 PSScavenge::reference_processor()->weak_oops_do( | |
2474 adjust_root_pointer_closure()); | |
2475 } | |
2476 | |
2477 void PSParallelCompact::compact_perm(ParCompactionManager* cm) { | |
2478 EventMark m("4 compact perm"); | |
2479 TraceTime tm("compact perm gen", print_phases(), true, gclog_or_tty); | |
2480 // trace("4"); | |
2481 | |
2482 gc_heap()->perm_gen()->start_array()->reset(); | |
2483 move_and_update(cm, perm_space_id); | |
2484 } | |
2485 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2486 void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2487 uint parallel_gc_threads) |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2488 { |
0 | 2489 TraceTime tm("drain task setup", print_phases(), true, gclog_or_tty); |
2490 | |
2491 const unsigned int task_count = MAX2(parallel_gc_threads, 1U); | |
2492 for (unsigned int j = 0; j < task_count; j++) { | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1638
diff
changeset
|
2493 q->enqueue(new DrainStacksCompactionTask(j)); |
0 | 2494 } |
2495 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2496 // Find all regions that are available (can be filled immediately) and |
0 | 2497 // distribute them to the thread stacks. The iteration is done in reverse |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2498 // order (high to low) so the regions will be removed in ascending order. |
0 | 2499 |
2500 const ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
2501 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2502 size_t fillable_regions = 0; // A count for diagnostic purposes. |
0 | 2503 unsigned int which = 0; // The worker thread number. |
2504 | |
2505 for (unsigned int id = to_space_id; id > perm_space_id; --id) { | |
2506 SpaceInfo* const space_info = _space_info + id; | |
2507 MutableSpace* const space = space_info->space(); | |
2508 HeapWord* const new_top = space_info->new_top(); | |
2509 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2510 const size_t beg_region = sd.addr_to_region_idx(space_info->dense_prefix()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2511 const size_t end_region = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2512 sd.addr_to_region_idx(sd.region_align_up(new_top)); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2513 assert(end_region > 0, "perm gen cannot be empty"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2514 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2515 for (size_t cur = end_region - 1; cur >= beg_region; --cur) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2516 if (sd.region(cur)->claim_unsafe()) { |
0 | 2517 ParCompactionManager* cm = ParCompactionManager::manager_array(which); |
1638 | 2518 cm->push_region(cur); |
0 | 2519 |
2520 if (TraceParallelOldGCCompactionPhase && Verbose) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2521 const size_t count_mod_8 = fillable_regions & 7; |
0 | 2522 if (count_mod_8 == 0) gclog_or_tty->print("fillable: "); |
264
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
2523 gclog_or_tty->print(" " SIZE_FORMAT_W(7), cur); |
0 | 2524 if (count_mod_8 == 7) gclog_or_tty->cr(); |
2525 } | |
2526 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2527 NOT_PRODUCT(++fillable_regions;) |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2528 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2529 // Assign regions to threads in round-robin fashion. |
0 | 2530 if (++which == task_count) { |
2531 which = 0; | |
2532 } | |
2533 } | |
2534 } | |
2535 } | |
2536 | |
2537 if (TraceParallelOldGCCompactionPhase) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2538 if (Verbose && (fillable_regions & 7) != 0) gclog_or_tty->cr(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2539 gclog_or_tty->print_cr("%u initially fillable regions", fillable_regions); |
0 | 2540 } |
2541 } | |
2542 | |
2543 #define PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING 4 | |
2544 | |
2545 void PSParallelCompact::enqueue_dense_prefix_tasks(GCTaskQueue* q, | |
2546 uint parallel_gc_threads) { | |
2547 TraceTime tm("dense prefix task setup", print_phases(), true, gclog_or_tty); | |
2548 | |
2549 ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
2550 | |
2551 // Iterate over all the spaces adding tasks for updating | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2552 // regions in the dense prefix. Assume that 1 gc thread |
0 | 2553 // will work on opening the gaps and the remaining gc threads |
2554 // will work on the dense prefix. | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2555 unsigned int space_id; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2556 for (space_id = old_space_id; space_id < last_space_id; ++ space_id) { |
0 | 2557 HeapWord* const dense_prefix_end = _space_info[space_id].dense_prefix(); |
2558 const MutableSpace* const space = _space_info[space_id].space(); | |
2559 | |
2560 if (dense_prefix_end == space->bottom()) { | |
2561 // There is no dense prefix for this space. | |
2562 continue; | |
2563 } | |
2564 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2565 // The dense prefix is before this region. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2566 size_t region_index_end_dense_prefix = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2567 sd.addr_to_region_idx(dense_prefix_end); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2568 RegionData* const dense_prefix_cp = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2569 sd.region(region_index_end_dense_prefix); |
0 | 2570 assert(dense_prefix_end == space->end() || |
2571 dense_prefix_cp->available() || | |
2572 dense_prefix_cp->claimed(), | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2573 "The region after the dense prefix should always be ready to fill"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2574 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2575 size_t region_index_start = sd.addr_to_region_idx(space->bottom()); |
0 | 2576 |
2577 // Is there dense prefix work? | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2578 size_t total_dense_prefix_regions = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2579 region_index_end_dense_prefix - region_index_start; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2580 // How many regions of the dense prefix should be given to |
0 | 2581 // each thread? |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2582 if (total_dense_prefix_regions > 0) { |
0 | 2583 uint tasks_for_dense_prefix = 1; |
2584 if (UseParallelDensePrefixUpdate) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2585 if (total_dense_prefix_regions <= |
0 | 2586 (parallel_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING)) { |
2587 // Don't over partition. This assumes that | |
2588 // PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING is a small integer value | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2589 // so there are not many regions to process. |
0 | 2590 tasks_for_dense_prefix = parallel_gc_threads; |
2591 } else { | |
2592 // Over partition | |
2593 tasks_for_dense_prefix = parallel_gc_threads * | |
2594 PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING; | |
2595 } | |
2596 } | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2597 size_t regions_per_thread = total_dense_prefix_regions / |
0 | 2598 tasks_for_dense_prefix; |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2599 // Give each thread at least 1 region. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2600 if (regions_per_thread == 0) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2601 regions_per_thread = 1; |
0 | 2602 } |
2603 | |
2604 for (uint k = 0; k < tasks_for_dense_prefix; k++) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2605 if (region_index_start >= region_index_end_dense_prefix) { |
0 | 2606 break; |
2607 } | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2608 // region_index_end is not processed |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2609 size_t region_index_end = MIN2(region_index_start + regions_per_thread, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2610 region_index_end_dense_prefix); |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2611 q->enqueue(new UpdateDensePrefixTask(SpaceId(space_id), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2612 region_index_start, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2613 region_index_end)); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2614 region_index_start = region_index_end; |
0 | 2615 } |
2616 } | |
2617 // This gets any part of the dense prefix that did not | |
2618 // fit evenly. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2619 if (region_index_start < region_index_end_dense_prefix) { |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2620 q->enqueue(new UpdateDensePrefixTask(SpaceId(space_id), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2621 region_index_start, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2622 region_index_end_dense_prefix)); |
0 | 2623 } |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2624 } |
0 | 2625 } |
2626 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2627 void PSParallelCompact::enqueue_region_stealing_tasks( |
0 | 2628 GCTaskQueue* q, |
2629 ParallelTaskTerminator* terminator_ptr, | |
2630 uint parallel_gc_threads) { | |
2631 TraceTime tm("steal task setup", print_phases(), true, gclog_or_tty); | |
2632 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2633 // Once a thread has drained it's stack, it should try to steal regions from |
0 | 2634 // other threads. |
2635 if (parallel_gc_threads > 1) { | |
2636 for (uint j = 0; j < parallel_gc_threads; j++) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2637 q->enqueue(new StealRegionCompactionTask(terminator_ptr)); |
0 | 2638 } |
2639 } | |
2640 } | |
2641 | |
2642 void PSParallelCompact::compact() { | |
2643 EventMark m("5 compact"); | |
2644 // trace("5"); | |
2645 TraceTime tm("compaction phase", print_phases(), true, gclog_or_tty); | |
2646 | |
2647 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
2648 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
2649 PSOldGen* old_gen = heap->old_gen(); | |
2650 old_gen->start_array()->reset(); | |
2651 uint parallel_gc_threads = heap->gc_task_manager()->workers(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2652 TaskQueueSetSuper* qset = ParCompactionManager::region_array(); |
0 | 2653 ParallelTaskTerminator terminator(parallel_gc_threads, qset); |
2654 | |
2655 GCTaskQueue* q = GCTaskQueue::create(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2656 enqueue_region_draining_tasks(q, parallel_gc_threads); |
0 | 2657 enqueue_dense_prefix_tasks(q, parallel_gc_threads); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2658 enqueue_region_stealing_tasks(q, &terminator, parallel_gc_threads); |
0 | 2659 |
2660 { | |
2661 TraceTime tm_pc("par compact", print_phases(), true, gclog_or_tty); | |
2662 | |
2663 WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create(); | |
2664 q->enqueue(fin); | |
2665 | |
2666 gc_task_manager()->add_list(q); | |
2667 | |
2668 fin->wait_for(); | |
2669 | |
2670 // We have to release the barrier tasks! | |
2671 WaitForBarrierGCTask::destroy(fin); | |
2672 | |
2673 #ifdef ASSERT | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2674 // Verify that all regions have been processed before the deferred updates. |
0 | 2675 // Note that perm_space_id is skipped; this type of verification is not |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2676 // valid until the perm gen is compacted by regions. |
0 | 2677 for (unsigned int id = old_space_id; id < last_space_id; ++id) { |
2678 verify_complete(SpaceId(id)); | |
2679 } | |
2680 #endif | |
2681 } | |
2682 | |
2683 { | |
2684 // Update the deferred objects, if any. Any compaction manager can be used. | |
2685 TraceTime tm_du("deferred updates", print_phases(), true, gclog_or_tty); | |
2686 ParCompactionManager* cm = ParCompactionManager::manager_array(0); | |
2687 for (unsigned int id = old_space_id; id < last_space_id; ++id) { | |
2688 update_deferred_objects(cm, SpaceId(id)); | |
2689 } | |
2690 } | |
2691 } | |
2692 | |
2693 #ifdef ASSERT | |
2694 void PSParallelCompact::verify_complete(SpaceId space_id) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2695 // All Regions between space bottom() to new_top() should be marked as filled |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2696 // and all Regions between new_top() and top() should be available (i.e., |
0 | 2697 // should have been emptied). |
2698 ParallelCompactData& sd = summary_data(); | |
2699 SpaceInfo si = _space_info[space_id]; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2700 HeapWord* new_top_addr = sd.region_align_up(si.new_top()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2701 HeapWord* old_top_addr = sd.region_align_up(si.space()->top()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2702 const size_t beg_region = sd.addr_to_region_idx(si.space()->bottom()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2703 const size_t new_top_region = sd.addr_to_region_idx(new_top_addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2704 const size_t old_top_region = sd.addr_to_region_idx(old_top_addr); |
0 | 2705 |
2706 bool issued_a_warning = false; | |
2707 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2708 size_t cur_region; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2709 for (cur_region = beg_region; cur_region < new_top_region; ++cur_region) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2710 const RegionData* const c = sd.region(cur_region); |
0 | 2711 if (!c->completed()) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2712 warning("region " SIZE_FORMAT " not filled: " |
0 | 2713 "destination_count=" SIZE_FORMAT, |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2714 cur_region, c->destination_count()); |
0 | 2715 issued_a_warning = true; |
2716 } | |
2717 } | |
2718 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2719 for (cur_region = new_top_region; cur_region < old_top_region; ++cur_region) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2720 const RegionData* const c = sd.region(cur_region); |
0 | 2721 if (!c->available()) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2722 warning("region " SIZE_FORMAT " not empty: " |
0 | 2723 "destination_count=" SIZE_FORMAT, |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2724 cur_region, c->destination_count()); |
0 | 2725 issued_a_warning = true; |
2726 } | |
2727 } | |
2728 | |
2729 if (issued_a_warning) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2730 print_region_ranges(); |
0 | 2731 } |
2732 } | |
2733 #endif // #ifdef ASSERT | |
2734 | |
2735 void PSParallelCompact::compact_serial(ParCompactionManager* cm) { | |
2736 EventMark m("5 compact serial"); | |
2737 TraceTime tm("compact serial", print_phases(), true, gclog_or_tty); | |
2738 | |
2739 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
2740 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
2741 | |
2742 PSYoungGen* young_gen = heap->young_gen(); | |
2743 PSOldGen* old_gen = heap->old_gen(); | |
2744 | |
2745 old_gen->start_array()->reset(); | |
2746 old_gen->move_and_update(cm); | |
2747 young_gen->move_and_update(cm); | |
2748 } | |
2749 | |
2750 void | |
941 | 2751 PSParallelCompact::follow_weak_klass_links() { |
0 | 2752 // All klasses on the revisit stack are marked at this point. |
2753 // Update and follow all subklass, sibling and implementor links. | |
941 | 2754 if (PrintRevisitStats) { |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2755 gclog_or_tty->print_cr("#classes in system dictionary = %d", |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2756 SystemDictionary::number_of_classes()); |
941 | 2757 } |
2758 for (uint i = 0; i < ParallelGCThreads + 1; i++) { | |
0 | 2759 ParCompactionManager* cm = ParCompactionManager::manager_array(i); |
2760 KeepAliveClosure keep_alive_closure(cm); | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2761 Stack<Klass*>* const rks = cm->revisit_klass_stack(); |
941 | 2762 if (PrintRevisitStats) { |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2763 gclog_or_tty->print_cr("Revisit klass stack[%u] length = " SIZE_FORMAT, |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2764 i, rks->size()); |
941 | 2765 } |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2766 while (!rks->is_empty()) { |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2767 Klass* const k = rks->pop(); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2768 k->follow_weak_klass_links(is_alive_closure(), &keep_alive_closure); |
0 | 2769 } |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2770 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
997
diff
changeset
|
2771 cm->follow_marking_stacks(); |
0 | 2772 } |
2773 } | |
2774 | |
2775 void | |
2776 PSParallelCompact::revisit_weak_klass_link(ParCompactionManager* cm, Klass* k) { | |
2777 cm->revisit_klass_stack()->push(k); | |
2778 } | |
2779 | |
941 | 2780 void PSParallelCompact::revisit_mdo(ParCompactionManager* cm, DataLayout* p) { |
2781 cm->revisit_mdo_stack()->push(p); | |
2782 } | |
2783 | |
2784 void PSParallelCompact::follow_mdo_weak_refs() { | |
2785 // All strongly reachable oops have been marked at this point; | |
2786 // we can visit and clear any weak references from MDO's which | |
2787 // we memoized during the strong marking phase. | |
2788 if (PrintRevisitStats) { | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2789 gclog_or_tty->print_cr("#classes in system dictionary = %d", |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2790 SystemDictionary::number_of_classes()); |
941 | 2791 } |
2792 for (uint i = 0; i < ParallelGCThreads + 1; i++) { | |
2793 ParCompactionManager* cm = ParCompactionManager::manager_array(i); | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2794 Stack<DataLayout*>* rms = cm->revisit_mdo_stack(); |
941 | 2795 if (PrintRevisitStats) { |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2796 gclog_or_tty->print_cr("Revisit MDO stack[%u] size = " SIZE_FORMAT, |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2797 i, rms->size()); |
941 | 2798 } |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2799 while (!rms->is_empty()) { |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2800 rms->pop()->follow_weak_refs(is_alive_closure()); |
941 | 2801 } |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2802 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
997
diff
changeset
|
2803 cm->follow_marking_stacks(); |
941 | 2804 } |
2805 } | |
2806 | |
2807 | |
0 | 2808 #ifdef VALIDATE_MARK_SWEEP |
2809 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
2810 void PSParallelCompact::track_adjusted_pointer(void* p, bool isroot) { |
0 | 2811 if (!ValidateMarkSweep) |
2812 return; | |
2813 | |
2814 if (!isroot) { | |
2815 if (_pointer_tracking) { | |
2816 guarantee(_adjusted_pointers->contains(p), "should have seen this pointer"); | |
2817 _adjusted_pointers->remove(p); | |
2818 } | |
2819 } else { | |
2820 ptrdiff_t index = _root_refs_stack->find(p); | |
2821 if (index != -1) { | |
2822 int l = _root_refs_stack->length(); | |
2823 if (l > 0 && l - 1 != index) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
2824 void* last = _root_refs_stack->pop(); |
0 | 2825 assert(last != p, "should be different"); |
2826 _root_refs_stack->at_put(index, last); | |
2827 } else { | |
2828 _root_refs_stack->remove(p); | |
2829 } | |
2830 } | |
2831 } | |
2832 } | |
2833 | |
2834 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
2835 void PSParallelCompact::check_adjust_pointer(void* p) { |
0 | 2836 _adjusted_pointers->push(p); |
2837 } | |
2838 | |
2839 | |
2840 class AdjusterTracker: public OopClosure { | |
2841 public: | |
2842 AdjusterTracker() {}; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
2843 void do_oop(oop* o) { PSParallelCompact::check_adjust_pointer(o); } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
2844 void do_oop(narrowOop* o) { PSParallelCompact::check_adjust_pointer(o); } |
0 | 2845 }; |
2846 | |
2847 | |
2848 void PSParallelCompact::track_interior_pointers(oop obj) { | |
2849 if (ValidateMarkSweep) { | |
2850 _adjusted_pointers->clear(); | |
2851 _pointer_tracking = true; | |
2852 | |
2853 AdjusterTracker checker; | |
2854 obj->oop_iterate(&checker); | |
2855 } | |
2856 } | |
2857 | |
2858 | |
2859 void PSParallelCompact::check_interior_pointers() { | |
2860 if (ValidateMarkSweep) { | |
2861 _pointer_tracking = false; | |
2862 guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers"); | |
2863 } | |
2864 } | |
2865 | |
2866 | |
2867 void PSParallelCompact::reset_live_oop_tracking(bool at_perm) { | |
2868 if (ValidateMarkSweep) { | |
2869 guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops"); | |
2870 _live_oops_index = at_perm ? _live_oops_index_at_perm : 0; | |
2871 } | |
2872 } | |
2873 | |
2874 | |
2875 void PSParallelCompact::register_live_oop(oop p, size_t size) { | |
2876 if (ValidateMarkSweep) { | |
2877 _live_oops->push(p); | |
2878 _live_oops_size->push(size); | |
2879 _live_oops_index++; | |
2880 } | |
2881 } | |
2882 | |
2883 void PSParallelCompact::validate_live_oop(oop p, size_t size) { | |
2884 if (ValidateMarkSweep) { | |
2885 oop obj = _live_oops->at((int)_live_oops_index); | |
2886 guarantee(obj == p, "should be the same object"); | |
2887 guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size"); | |
2888 _live_oops_index++; | |
2889 } | |
2890 } | |
2891 | |
2892 void PSParallelCompact::live_oop_moved_to(HeapWord* q, size_t size, | |
2893 HeapWord* compaction_top) { | |
2894 assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top), | |
2895 "should be moved to forwarded location"); | |
2896 if (ValidateMarkSweep) { | |
2897 PSParallelCompact::validate_live_oop(oop(q), size); | |
2898 _live_oops_moved_to->push(oop(compaction_top)); | |
2899 } | |
2900 if (RecordMarkSweepCompaction) { | |
2901 _cur_gc_live_oops->push(q); | |
2902 _cur_gc_live_oops_moved_to->push(compaction_top); | |
2903 _cur_gc_live_oops_size->push(size); | |
2904 } | |
2905 } | |
2906 | |
2907 | |
2908 void PSParallelCompact::compaction_complete() { | |
2909 if (RecordMarkSweepCompaction) { | |
2910 GrowableArray<HeapWord*>* _tmp_live_oops = _cur_gc_live_oops; | |
2911 GrowableArray<HeapWord*>* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to; | |
2912 GrowableArray<size_t> * _tmp_live_oops_size = _cur_gc_live_oops_size; | |
2913 | |
2914 _cur_gc_live_oops = _last_gc_live_oops; | |
2915 _cur_gc_live_oops_moved_to = _last_gc_live_oops_moved_to; | |
2916 _cur_gc_live_oops_size = _last_gc_live_oops_size; | |
2917 _last_gc_live_oops = _tmp_live_oops; | |
2918 _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to; | |
2919 _last_gc_live_oops_size = _tmp_live_oops_size; | |
2920 } | |
2921 } | |
2922 | |
2923 | |
2924 void PSParallelCompact::print_new_location_of_heap_address(HeapWord* q) { | |
2925 if (!RecordMarkSweepCompaction) { | |
2926 tty->print_cr("Requires RecordMarkSweepCompaction to be enabled"); | |
2927 return; | |
2928 } | |
2929 | |
2930 if (_last_gc_live_oops == NULL) { | |
2931 tty->print_cr("No compaction information gathered yet"); | |
2932 return; | |
2933 } | |
2934 | |
2935 for (int i = 0; i < _last_gc_live_oops->length(); i++) { | |
2936 HeapWord* old_oop = _last_gc_live_oops->at(i); | |
2937 size_t sz = _last_gc_live_oops_size->at(i); | |
2938 if (old_oop <= q && q < (old_oop + sz)) { | |
2939 HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i); | |
2940 size_t offset = (q - old_oop); | |
2941 tty->print_cr("Address " PTR_FORMAT, q); | |
2942 tty->print_cr(" Was in oop " PTR_FORMAT ", size %d, at offset %d", old_oop, sz, offset); | |
2943 tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset); | |
2944 return; | |
2945 } | |
2946 } | |
2947 | |
2948 tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q); | |
2949 } | |
2950 #endif //VALIDATE_MARK_SWEEP | |
2951 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2952 // Update interior oops in the ranges of regions [beg_region, end_region). |
0 | 2953 void |
2954 PSParallelCompact::update_and_deadwood_in_dense_prefix(ParCompactionManager* cm, | |
2955 SpaceId space_id, | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2956 size_t beg_region, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2957 size_t end_region) { |
0 | 2958 ParallelCompactData& sd = summary_data(); |
2959 ParMarkBitMap* const mbm = mark_bitmap(); | |
2960 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2961 HeapWord* beg_addr = sd.region_to_addr(beg_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2962 HeapWord* const end_addr = sd.region_to_addr(end_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2963 assert(beg_region <= end_region, "bad region range"); |
0 | 2964 assert(end_addr <= dense_prefix(space_id), "not in the dense prefix"); |
2965 | |
2966 #ifdef ASSERT | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2967 // Claim the regions to avoid triggering an assert when they are marked as |
0 | 2968 // filled. |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2969 for (size_t claim_region = beg_region; claim_region < end_region; ++claim_region) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2970 assert(sd.region(claim_region)->claim_unsafe(), "claim() failed"); |
0 | 2971 } |
2972 #endif // #ifdef ASSERT | |
2973 | |
2974 if (beg_addr != space(space_id)->bottom()) { | |
2975 // Find the first live object or block of dead space that *starts* in this | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2976 // range of regions. If a partial object crosses onto the region, skip it; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2977 // it will be marked for 'deferred update' when the object head is |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2978 // processed. If dead space crosses onto the region, it is also skipped; it |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2979 // will be filled when the prior region is processed. If neither of those |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2980 // apply, the first word in the region is the start of a live object or dead |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2981 // space. |
0 | 2982 assert(beg_addr > space(space_id)->bottom(), "sanity"); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2983 const RegionData* const cp = sd.region(beg_region); |
0 | 2984 if (cp->partial_obj_size() != 0) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2985 beg_addr = sd.partial_obj_end(beg_region); |
0 | 2986 } else if (dead_space_crosses_boundary(cp, mbm->addr_to_bit(beg_addr))) { |
2987 beg_addr = mbm->find_obj_beg(beg_addr, end_addr); | |
2988 } | |
2989 } | |
2990 | |
2991 if (beg_addr < end_addr) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2992 // A live object or block of dead space starts in this range of Regions. |
0 | 2993 HeapWord* const dense_prefix_end = dense_prefix(space_id); |
2994 | |
2995 // Create closures and iterate. | |
2996 UpdateOnlyClosure update_closure(mbm, cm, space_id); | |
2997 FillClosure fill_closure(cm, space_id); | |
2998 ParMarkBitMap::IterationStatus status; | |
2999 status = mbm->iterate(&update_closure, &fill_closure, beg_addr, end_addr, | |
3000 dense_prefix_end); | |
3001 if (status == ParMarkBitMap::incomplete) { | |
3002 update_closure.do_addr(update_closure.source()); | |
3003 } | |
3004 } | |
3005 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3006 // Mark the regions as filled. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3007 RegionData* const beg_cp = sd.region(beg_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3008 RegionData* const end_cp = sd.region(end_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3009 for (RegionData* cp = beg_cp; cp < end_cp; ++cp) { |
0 | 3010 cp->set_completed(); |
3011 } | |
3012 } | |
3013 | |
3014 // Return the SpaceId for the space containing addr. If addr is not in the | |
3015 // heap, last_space_id is returned. In debug mode it expects the address to be | |
3016 // in the heap and asserts such. | |
3017 PSParallelCompact::SpaceId PSParallelCompact::space_id(HeapWord* addr) { | |
3018 assert(Universe::heap()->is_in_reserved(addr), "addr not in the heap"); | |
3019 | |
3020 for (unsigned int id = perm_space_id; id < last_space_id; ++id) { | |
3021 if (_space_info[id].space()->contains(addr)) { | |
3022 return SpaceId(id); | |
3023 } | |
3024 } | |
3025 | |
3026 assert(false, "no space contains the addr"); | |
3027 return last_space_id; | |
3028 } | |
3029 | |
3030 void PSParallelCompact::update_deferred_objects(ParCompactionManager* cm, | |
3031 SpaceId id) { | |
3032 assert(id < last_space_id, "bad space id"); | |
3033 | |
3034 ParallelCompactData& sd = summary_data(); | |
3035 const SpaceInfo* const space_info = _space_info + id; | |
3036 ObjectStartArray* const start_array = space_info->start_array(); | |
3037 | |
3038 const MutableSpace* const space = space_info->space(); | |
3039 assert(space_info->dense_prefix() >= space->bottom(), "dense_prefix not set"); | |
3040 HeapWord* const beg_addr = space_info->dense_prefix(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3041 HeapWord* const end_addr = sd.region_align_up(space_info->new_top()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3042 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3043 const RegionData* const beg_region = sd.addr_to_region_ptr(beg_addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3044 const RegionData* const end_region = sd.addr_to_region_ptr(end_addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3045 const RegionData* cur_region; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3046 for (cur_region = beg_region; cur_region < end_region; ++cur_region) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3047 HeapWord* const addr = cur_region->deferred_obj_addr(); |
0 | 3048 if (addr != NULL) { |
3049 if (start_array != NULL) { | |
3050 start_array->allocate_block(addr); | |
3051 } | |
3052 oop(addr)->update_contents(cm); | |
3053 assert(oop(addr)->is_oop_or_null(), "should be an oop now"); | |
3054 } | |
3055 } | |
3056 } | |
3057 | |
3058 // Skip over count live words starting from beg, and return the address of the | |
3059 // next live word. Unless marked, the word corresponding to beg is assumed to | |
3060 // be dead. Callers must either ensure beg does not correspond to the middle of | |
3061 // an object, or account for those live words in some other way. Callers must | |
3062 // also ensure that there are enough live words in the range [beg, end) to skip. | |
3063 HeapWord* | |
3064 PSParallelCompact::skip_live_words(HeapWord* beg, HeapWord* end, size_t count) | |
3065 { | |
3066 assert(count > 0, "sanity"); | |
3067 | |
3068 ParMarkBitMap* m = mark_bitmap(); | |
3069 idx_t bits_to_skip = m->words_to_bits(count); | |
3070 idx_t cur_beg = m->addr_to_bit(beg); | |
3071 const idx_t search_end = BitMap::word_align_up(m->addr_to_bit(end)); | |
3072 | |
3073 do { | |
3074 cur_beg = m->find_obj_beg(cur_beg, search_end); | |
3075 idx_t cur_end = m->find_obj_end(cur_beg, search_end); | |
3076 const size_t obj_bits = cur_end - cur_beg + 1; | |
3077 if (obj_bits > bits_to_skip) { | |
3078 return m->bit_to_addr(cur_beg + bits_to_skip); | |
3079 } | |
3080 bits_to_skip -= obj_bits; | |
3081 cur_beg = cur_end + 1; | |
3082 } while (bits_to_skip > 0); | |
3083 | |
3084 // Skipping the desired number of words landed just past the end of an object. | |
3085 // Find the start of the next object. | |
3086 cur_beg = m->find_obj_beg(cur_beg, search_end); | |
3087 assert(cur_beg < m->addr_to_bit(end), "not enough live words to skip"); | |
3088 return m->bit_to_addr(cur_beg); | |
3089 } | |
3090 | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3091 HeapWord* PSParallelCompact::first_src_addr(HeapWord* const dest_addr, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3092 SpaceId src_space_id, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3093 size_t src_region_idx) |
0 | 3094 { |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3095 assert(summary_data().is_region_aligned(dest_addr), "not aligned"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3096 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3097 const SplitInfo& split_info = _space_info[src_space_id].split_info(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3098 if (split_info.dest_region_addr() == dest_addr) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3099 // The partial object ending at the split point contains the first word to |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3100 // be copied to dest_addr. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3101 return split_info.first_src_addr(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3102 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3103 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3104 const ParallelCompactData& sd = summary_data(); |
0 | 3105 ParMarkBitMap* const bitmap = mark_bitmap(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3106 const size_t RegionSize = ParallelCompactData::RegionSize; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3107 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3108 assert(sd.is_region_aligned(dest_addr), "not aligned"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3109 const RegionData* const src_region_ptr = sd.region(src_region_idx); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3110 const size_t partial_obj_size = src_region_ptr->partial_obj_size(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3111 HeapWord* const src_region_destination = src_region_ptr->destination(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3112 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3113 assert(dest_addr >= src_region_destination, "wrong src region"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3114 assert(src_region_ptr->data_size() > 0, "src region cannot be empty"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3115 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3116 HeapWord* const src_region_beg = sd.region_to_addr(src_region_idx); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3117 HeapWord* const src_region_end = src_region_beg + RegionSize; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3118 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3119 HeapWord* addr = src_region_beg; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3120 if (dest_addr == src_region_destination) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3121 // Return the first live word in the source region. |
0 | 3122 if (partial_obj_size == 0) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3123 addr = bitmap->find_obj_beg(addr, src_region_end); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3124 assert(addr < src_region_end, "no objects start in src region"); |
0 | 3125 } |
3126 return addr; | |
3127 } | |
3128 | |
3129 // Must skip some live data. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3130 size_t words_to_skip = dest_addr - src_region_destination; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3131 assert(src_region_ptr->data_size() > words_to_skip, "wrong src region"); |
0 | 3132 |
3133 if (partial_obj_size >= words_to_skip) { | |
3134 // All the live words to skip are part of the partial object. | |
3135 addr += words_to_skip; | |
3136 if (partial_obj_size == words_to_skip) { | |
3137 // Find the first live word past the partial object. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3138 addr = bitmap->find_obj_beg(addr, src_region_end); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3139 assert(addr < src_region_end, "wrong src region"); |
0 | 3140 } |
3141 return addr; | |
3142 } | |
3143 | |
3144 // Skip over the partial object (if any). | |
3145 if (partial_obj_size != 0) { | |
3146 words_to_skip -= partial_obj_size; | |
3147 addr += partial_obj_size; | |
3148 } | |
3149 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3150 // Skip over live words due to objects that start in the region. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3151 addr = skip_live_words(addr, src_region_end, words_to_skip); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3152 assert(addr < src_region_end, "wrong src region"); |
0 | 3153 return addr; |
3154 } | |
3155 | |
3156 void PSParallelCompact::decrement_destination_counts(ParCompactionManager* cm, | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3157 SpaceId src_space_id, |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3158 size_t beg_region, |
0 | 3159 HeapWord* end_addr) |
3160 { | |
3161 ParallelCompactData& sd = summary_data(); | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3162 |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3163 #ifdef ASSERT |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3164 MutableSpace* const src_space = _space_info[src_space_id].space(); |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3165 HeapWord* const beg_addr = sd.region_to_addr(beg_region); |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3166 assert(src_space->contains(beg_addr) || beg_addr == src_space->end(), |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3167 "src_space_id does not match beg_addr"); |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3168 assert(src_space->contains(end_addr) || end_addr == src_space->end(), |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3169 "src_space_id does not match end_addr"); |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3170 #endif // #ifdef ASSERT |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3171 |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3172 RegionData* const beg = sd.region(beg_region); |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3173 RegionData* const end = sd.addr_to_region_ptr(sd.region_align_up(end_addr)); |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3174 |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3175 // Regions up to new_top() are enqueued if they become available. |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3176 HeapWord* const new_top = _space_info[src_space_id].new_top(); |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3177 RegionData* const enqueue_end = |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3178 sd.addr_to_region_ptr(sd.region_align_up(new_top)); |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3179 |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3180 for (RegionData* cur = beg; cur < end; ++cur) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3181 assert(cur->data_size() > 0, "region must have live data"); |
0 | 3182 cur->decrement_destination_count(); |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3183 if (cur < enqueue_end && cur->available() && cur->claim()) { |
1638 | 3184 cm->push_region(sd.region(cur)); |
0 | 3185 } |
3186 } | |
3187 } | |
3188 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3189 size_t PSParallelCompact::next_src_region(MoveAndUpdateClosure& closure, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3190 SpaceId& src_space_id, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3191 HeapWord*& src_space_top, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3192 HeapWord* end_addr) |
0 | 3193 { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3194 typedef ParallelCompactData::RegionData RegionData; |
0 | 3195 |
3196 ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3197 const size_t region_size = ParallelCompactData::RegionSize; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3198 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3199 size_t src_region_idx = 0; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3200 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3201 // Skip empty regions (if any) up to the top of the space. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3202 HeapWord* const src_aligned_up = sd.region_align_up(end_addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3203 RegionData* src_region_ptr = sd.addr_to_region_ptr(src_aligned_up); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3204 HeapWord* const top_aligned_up = sd.region_align_up(src_space_top); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3205 const RegionData* const top_region_ptr = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3206 sd.addr_to_region_ptr(top_aligned_up); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3207 while (src_region_ptr < top_region_ptr && src_region_ptr->data_size() == 0) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3208 ++src_region_ptr; |
0 | 3209 } |
3210 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3211 if (src_region_ptr < top_region_ptr) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3212 // The next source region is in the current space. Update src_region_idx |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3213 // and the source address to match src_region_ptr. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3214 src_region_idx = sd.region(src_region_ptr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3215 HeapWord* const src_region_addr = sd.region_to_addr(src_region_idx); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3216 if (src_region_addr > closure.source()) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3217 closure.set_source(src_region_addr); |
0 | 3218 } |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3219 return src_region_idx; |
0 | 3220 } |
3221 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3222 // Switch to a new source space and find the first non-empty region. |
0 | 3223 unsigned int space_id = src_space_id + 1; |
3224 assert(space_id < last_space_id, "not enough spaces"); | |
3225 | |
3226 HeapWord* const destination = closure.destination(); | |
3227 | |
3228 do { | |
3229 MutableSpace* space = _space_info[space_id].space(); | |
3230 HeapWord* const bottom = space->bottom(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3231 const RegionData* const bottom_cp = sd.addr_to_region_ptr(bottom); |
0 | 3232 |
3233 // Iterate over the spaces that do not compact into themselves. | |
3234 if (bottom_cp->destination() != bottom) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3235 HeapWord* const top_aligned_up = sd.region_align_up(space->top()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3236 const RegionData* const top_cp = sd.addr_to_region_ptr(top_aligned_up); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3237 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3238 for (const RegionData* src_cp = bottom_cp; src_cp < top_cp; ++src_cp) { |
0 | 3239 if (src_cp->live_obj_size() > 0) { |
3240 // Found it. | |
3241 assert(src_cp->destination() == destination, | |
3242 "first live obj in the space must match the destination"); | |
3243 assert(src_cp->partial_obj_size() == 0, | |
3244 "a space cannot begin with a partial obj"); | |
3245 | |
3246 src_space_id = SpaceId(space_id); | |
3247 src_space_top = space->top(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3248 const size_t src_region_idx = sd.region(src_cp); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3249 closure.set_source(sd.region_to_addr(src_region_idx)); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3250 return src_region_idx; |
0 | 3251 } else { |
3252 assert(src_cp->data_size() == 0, "sanity"); | |
3253 } | |
3254 } | |
3255 } | |
3256 } while (++space_id < last_space_id); | |
3257 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3258 assert(false, "no source region was found"); |
0 | 3259 return 0; |
3260 } | |
3261 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3262 void PSParallelCompact::fill_region(ParCompactionManager* cm, size_t region_idx) |
0 | 3263 { |
3264 typedef ParMarkBitMap::IterationStatus IterationStatus; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3265 const size_t RegionSize = ParallelCompactData::RegionSize; |
0 | 3266 ParMarkBitMap* const bitmap = mark_bitmap(); |
3267 ParallelCompactData& sd = summary_data(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3268 RegionData* const region_ptr = sd.region(region_idx); |
0 | 3269 |
3270 // Get the items needed to construct the closure. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3271 HeapWord* dest_addr = sd.region_to_addr(region_idx); |
0 | 3272 SpaceId dest_space_id = space_id(dest_addr); |
3273 ObjectStartArray* start_array = _space_info[dest_space_id].start_array(); | |
3274 HeapWord* new_top = _space_info[dest_space_id].new_top(); | |
3275 assert(dest_addr < new_top, "sanity"); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3276 const size_t words = MIN2(pointer_delta(new_top, dest_addr), RegionSize); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3277 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3278 // Get the source region and related info. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3279 size_t src_region_idx = region_ptr->source_region(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3280 SpaceId src_space_id = space_id(sd.region_to_addr(src_region_idx)); |
0 | 3281 HeapWord* src_space_top = _space_info[src_space_id].space()->top(); |
3282 | |
3283 MoveAndUpdateClosure closure(bitmap, cm, start_array, dest_addr, words); | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3284 closure.set_source(first_src_addr(dest_addr, src_space_id, src_region_idx)); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3285 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3286 // Adjust src_region_idx to prepare for decrementing destination counts (the |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3287 // destination count is not decremented when a region is copied to itself). |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3288 if (src_region_idx == region_idx) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3289 src_region_idx += 1; |
0 | 3290 } |
3291 | |
3292 if (bitmap->is_unmarked(closure.source())) { | |
3293 // The first source word is in the middle of an object; copy the remainder | |
3294 // of the object or as much as will fit. The fact that pointer updates were | |
3295 // deferred will be noted when the object header is processed. | |
3296 HeapWord* const old_src_addr = closure.source(); | |
3297 closure.copy_partial_obj(); | |
3298 if (closure.is_full()) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3299 decrement_destination_counts(cm, src_space_id, src_region_idx, |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3300 closure.source()); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3301 region_ptr->set_deferred_obj_addr(NULL); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3302 region_ptr->set_completed(); |
0 | 3303 return; |
3304 } | |
3305 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3306 HeapWord* const end_addr = sd.region_align_down(closure.source()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3307 if (sd.region_align_down(old_src_addr) != end_addr) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3308 // The partial object was copied from more than one source region. |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3309 decrement_destination_counts(cm, src_space_id, src_region_idx, end_addr); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3310 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3311 // Move to the next source region, possibly switching spaces as well. All |
0 | 3312 // args except end_addr may be modified. |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3313 src_region_idx = next_src_region(closure, src_space_id, src_space_top, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3314 end_addr); |
0 | 3315 } |
3316 } | |
3317 | |
3318 do { | |
3319 HeapWord* const cur_addr = closure.source(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3320 HeapWord* const end_addr = MIN2(sd.region_align_up(cur_addr + 1), |
0 | 3321 src_space_top); |
3322 IterationStatus status = bitmap->iterate(&closure, cur_addr, end_addr); | |
3323 | |
3324 if (status == ParMarkBitMap::incomplete) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3325 // The last obj that starts in the source region does not end in the |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3326 // region. |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
1387
diff
changeset
|
3327 assert(closure.source() < end_addr, "sanity"); |
0 | 3328 HeapWord* const obj_beg = closure.source(); |
3329 HeapWord* const range_end = MIN2(obj_beg + closure.words_remaining(), | |
3330 src_space_top); | |
3331 HeapWord* const obj_end = bitmap->find_obj_end(obj_beg, range_end); | |
3332 if (obj_end < range_end) { | |
3333 // The end was found; the entire object will fit. | |
3334 status = closure.do_addr(obj_beg, bitmap->obj_size(obj_beg, obj_end)); | |
3335 assert(status != ParMarkBitMap::would_overflow, "sanity"); | |
3336 } else { | |
3337 // The end was not found; the object will not fit. | |
3338 assert(range_end < src_space_top, "obj cannot cross space boundary"); | |
3339 status = ParMarkBitMap::would_overflow; | |
3340 } | |
3341 } | |
3342 | |
3343 if (status == ParMarkBitMap::would_overflow) { | |
3344 // The last object did not fit. Note that interior oop updates were | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3345 // deferred, then copy enough of the object to fill the region. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3346 region_ptr->set_deferred_obj_addr(closure.destination()); |
0 | 3347 status = closure.copy_until_full(); // copies from closure.source() |
3348 | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3349 decrement_destination_counts(cm, src_space_id, src_region_idx, |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3350 closure.source()); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3351 region_ptr->set_completed(); |
0 | 3352 return; |
3353 } | |
3354 | |
3355 if (status == ParMarkBitMap::full) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3356 decrement_destination_counts(cm, src_space_id, src_region_idx, |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3357 closure.source()); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3358 region_ptr->set_deferred_obj_addr(NULL); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3359 region_ptr->set_completed(); |
0 | 3360 return; |
3361 } | |
3362 | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3363 decrement_destination_counts(cm, src_space_id, src_region_idx, end_addr); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3364 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3365 // Move to the next source region, possibly switching spaces as well. All |
0 | 3366 // args except end_addr may be modified. |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3367 src_region_idx = next_src_region(closure, src_space_id, src_space_top, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3368 end_addr); |
0 | 3369 } while (true); |
3370 } | |
3371 | |
3372 void | |
3373 PSParallelCompact::move_and_update(ParCompactionManager* cm, SpaceId space_id) { | |
3374 const MutableSpace* sp = space(space_id); | |
3375 if (sp->is_empty()) { | |
3376 return; | |
3377 } | |
3378 | |
3379 ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
3380 ParMarkBitMap* const bitmap = mark_bitmap(); | |
3381 HeapWord* const dp_addr = dense_prefix(space_id); | |
3382 HeapWord* beg_addr = sp->bottom(); | |
3383 HeapWord* end_addr = sp->top(); | |
3384 | |
3385 #ifdef ASSERT | |
3386 assert(beg_addr <= dp_addr && dp_addr <= end_addr, "bad dense prefix"); | |
3387 if (cm->should_verify_only()) { | |
3388 VerifyUpdateClosure verify_update(cm, sp); | |
3389 bitmap->iterate(&verify_update, beg_addr, end_addr); | |
3390 return; | |
3391 } | |
3392 | |
3393 if (cm->should_reset_only()) { | |
3394 ResetObjectsClosure reset_objects(cm); | |
3395 bitmap->iterate(&reset_objects, beg_addr, end_addr); | |
3396 return; | |
3397 } | |
3398 #endif | |
3399 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3400 const size_t beg_region = sd.addr_to_region_idx(beg_addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3401 const size_t dp_region = sd.addr_to_region_idx(dp_addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3402 if (beg_region < dp_region) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3403 update_and_deadwood_in_dense_prefix(cm, space_id, beg_region, dp_region); |
0 | 3404 } |
3405 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3406 // The destination of the first live object that starts in the region is one |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3407 // past the end of the partial object entering the region (if any). |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3408 HeapWord* const dest_addr = sd.partial_obj_end(dp_region); |
0 | 3409 HeapWord* const new_top = _space_info[space_id].new_top(); |
3410 assert(new_top >= dest_addr, "bad new_top value"); | |
3411 const size_t words = pointer_delta(new_top, dest_addr); | |
3412 | |
3413 if (words > 0) { | |
3414 ObjectStartArray* start_array = _space_info[space_id].start_array(); | |
3415 MoveAndUpdateClosure closure(bitmap, cm, start_array, dest_addr, words); | |
3416 | |
3417 ParMarkBitMap::IterationStatus status; | |
3418 status = bitmap->iterate(&closure, dest_addr, end_addr); | |
3419 assert(status == ParMarkBitMap::full, "iteration not complete"); | |
3420 assert(bitmap->find_obj_beg(closure.source(), end_addr) == end_addr, | |
3421 "live objects skipped because closure is full"); | |
3422 } | |
3423 } | |
3424 | |
3425 jlong PSParallelCompact::millis_since_last_gc() { | |
3426 jlong ret_val = os::javaTimeMillis() - _time_of_last_gc; | |
3427 // XXX See note in genCollectedHeap::millis_since_last_gc(). | |
3428 if (ret_val < 0) { | |
3429 NOT_PRODUCT(warning("time warp: %d", ret_val);) | |
3430 return 0; | |
3431 } | |
3432 return ret_val; | |
3433 } | |
3434 | |
3435 void PSParallelCompact::reset_millis_since_last_gc() { | |
3436 _time_of_last_gc = os::javaTimeMillis(); | |
3437 } | |
3438 | |
3439 ParMarkBitMap::IterationStatus MoveAndUpdateClosure::copy_until_full() | |
3440 { | |
3441 if (source() != destination()) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3442 DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());) |
0 | 3443 Copy::aligned_conjoint_words(source(), destination(), words_remaining()); |
3444 } | |
3445 update_state(words_remaining()); | |
3446 assert(is_full(), "sanity"); | |
3447 return ParMarkBitMap::full; | |
3448 } | |
3449 | |
3450 void MoveAndUpdateClosure::copy_partial_obj() | |
3451 { | |
3452 size_t words = words_remaining(); | |
3453 | |
3454 HeapWord* const range_end = MIN2(source() + words, bitmap()->region_end()); | |
3455 HeapWord* const end_addr = bitmap()->find_obj_end(source(), range_end); | |
3456 if (end_addr < range_end) { | |
3457 words = bitmap()->obj_size(source(), end_addr); | |
3458 } | |
3459 | |
3460 // This test is necessary; if omitted, the pointer updates to a partial object | |
3461 // that crosses the dense prefix boundary could be overwritten. | |
3462 if (source() != destination()) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3463 DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());) |
0 | 3464 Copy::aligned_conjoint_words(source(), destination(), words); |
3465 } | |
3466 update_state(words); | |
3467 } | |
3468 | |
3469 ParMarkBitMapClosure::IterationStatus | |
3470 MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) { | |
3471 assert(destination() != NULL, "sanity"); | |
3472 assert(bitmap()->obj_size(addr) == words, "bad size"); | |
3473 | |
3474 _source = addr; | |
3475 assert(PSParallelCompact::summary_data().calc_new_pointer(source()) == | |
3476 destination(), "wrong destination"); | |
3477 | |
3478 if (words > words_remaining()) { | |
3479 return ParMarkBitMap::would_overflow; | |
3480 } | |
3481 | |
3482 // The start_array must be updated even if the object is not moving. | |
3483 if (_start_array != NULL) { | |
3484 _start_array->allocate_block(destination()); | |
3485 } | |
3486 | |
3487 if (destination() != source()) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3488 DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());) |
0 | 3489 Copy::aligned_conjoint_words(source(), destination(), words); |
3490 } | |
3491 | |
3492 oop moved_oop = (oop) destination(); | |
3493 moved_oop->update_contents(compaction_manager()); | |
3494 assert(moved_oop->is_oop_or_null(), "Object should be whole at this point"); | |
3495 | |
3496 update_state(words); | |
3497 assert(destination() == (HeapWord*)moved_oop + moved_oop->size(), "sanity"); | |
3498 return is_full() ? ParMarkBitMap::full : ParMarkBitMap::incomplete; | |
3499 } | |
3500 | |
3501 UpdateOnlyClosure::UpdateOnlyClosure(ParMarkBitMap* mbm, | |
3502 ParCompactionManager* cm, | |
3503 PSParallelCompact::SpaceId space_id) : | |
3504 ParMarkBitMapClosure(mbm, cm), | |
3505 _space_id(space_id), | |
3506 _start_array(PSParallelCompact::start_array(space_id)) | |
3507 { | |
3508 } | |
3509 | |
3510 // Updates the references in the object to their new values. | |
3511 ParMarkBitMapClosure::IterationStatus | |
3512 UpdateOnlyClosure::do_addr(HeapWord* addr, size_t words) { | |
3513 do_addr(addr); | |
3514 return ParMarkBitMap::incomplete; | |
3515 } | |
3516 | |
3517 // Verify the new location using the forwarding pointer | |
3518 // from MarkSweep::mark_sweep_phase2(). Set the mark_word | |
3519 // to the initial value. | |
3520 ParMarkBitMapClosure::IterationStatus | |
3521 PSParallelCompact::VerifyUpdateClosure::do_addr(HeapWord* addr, size_t words) { | |
3522 // The second arg (words) is not used. | |
3523 oop obj = (oop) addr; | |
3524 HeapWord* forwarding_ptr = (HeapWord*) obj->mark()->decode_pointer(); | |
3525 HeapWord* new_pointer = summary_data().calc_new_pointer(obj); | |
3526 if (forwarding_ptr == NULL) { | |
3527 // The object is dead or not moving. | |
3528 assert(bitmap()->is_unmarked(obj) || (new_pointer == (HeapWord*) obj), | |
3529 "Object liveness is wrong."); | |
3530 return ParMarkBitMap::incomplete; | |
3531 } | |
3532 assert(UseParallelOldGCDensePrefix || | |
3533 (HeapMaximumCompactionInterval > 1) || | |
3534 (MarkSweepAlwaysCompactCount > 1) || | |
3535 (forwarding_ptr == new_pointer), | |
3536 "Calculation of new location is incorrect"); | |
3537 return ParMarkBitMap::incomplete; | |
3538 } | |
3539 | |
3540 // Reset objects modified for debug checking. | |
3541 ParMarkBitMapClosure::IterationStatus | |
3542 PSParallelCompact::ResetObjectsClosure::do_addr(HeapWord* addr, size_t words) { | |
3543 // The second arg (words) is not used. | |
3544 oop obj = (oop) addr; | |
3545 obj->init_mark(); | |
3546 return ParMarkBitMap::incomplete; | |
3547 } | |
3548 | |
3549 // Prepare for compaction. This method is executed once | |
3550 // (i.e., by a single thread) before compaction. | |
3551 // Save the updated location of the intArrayKlassObj for | |
3552 // filling holes in the dense prefix. | |
3553 void PSParallelCompact::compact_prologue() { | |
3554 _updated_int_array_klass_obj = (klassOop) | |
3555 summary_data().calc_new_pointer(Universe::intArrayKlassObj()); | |
3556 } | |
3557 |