Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @ 3979:4dfb2df418f2
6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
author | johnc |
---|---|
date | Thu, 22 Sep 2011 10:57:37 -0700 |
parents | c2bf0120ee5d |
children | bca17e38de00 |
rev | line source |
---|---|
0 | 1 /* |
2369
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2177
diff
changeset
|
2 * Copyright (c) 2005, 2011, 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(); | |
2369
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2177
diff
changeset
|
830 _ref_processor = |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2177
diff
changeset
|
831 new ReferenceProcessor(mr, // span |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2177
diff
changeset
|
832 ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2177
diff
changeset
|
833 (int) ParallelGCThreads, // mt processing degree |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2177
diff
changeset
|
834 true, // mt discovery |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2177
diff
changeset
|
835 (int) ParallelGCThreads, // mt discovery degree |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2177
diff
changeset
|
836 true, // atomic_discovery |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2177
diff
changeset
|
837 &_is_alive_closure, // non-header is alive closure |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2177
diff
changeset
|
838 false); // write barrier for next field updates |
0 | 839 _counters = new CollectorCounters("PSParallelCompact", 1); |
840 | |
841 // Initialize static fields in ParCompactionManager. | |
842 ParCompactionManager::initialize(mark_bitmap()); | |
843 } | |
844 | |
845 bool PSParallelCompact::initialize() { | |
846 ParallelScavengeHeap* heap = gc_heap(); | |
847 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
848 MemRegion mr = heap->reserved_region(); | |
849 | |
850 // Was the old gen get allocated successfully? | |
851 if (!heap->old_gen()->is_allocated()) { | |
852 return false; | |
853 } | |
854 | |
855 initialize_space_info(); | |
856 initialize_dead_wood_limiter(); | |
857 | |
858 if (!_mark_bitmap.initialize(mr)) { | |
859 vm_shutdown_during_initialization("Unable to allocate bit map for " | |
860 "parallel garbage collection for the requested heap size."); | |
861 return false; | |
862 } | |
863 | |
864 if (!_summary_data.initialize(mr)) { | |
865 vm_shutdown_during_initialization("Unable to allocate tables for " | |
866 "parallel garbage collection for the requested heap size."); | |
867 return false; | |
868 } | |
869 | |
870 return true; | |
871 } | |
872 | |
873 void PSParallelCompact::initialize_space_info() | |
874 { | |
875 memset(&_space_info, 0, sizeof(_space_info)); | |
876 | |
877 ParallelScavengeHeap* heap = gc_heap(); | |
878 PSYoungGen* young_gen = heap->young_gen(); | |
879 MutableSpace* perm_space = heap->perm_gen()->object_space(); | |
880 | |
881 _space_info[perm_space_id].set_space(perm_space); | |
882 _space_info[old_space_id].set_space(heap->old_gen()->object_space()); | |
883 _space_info[eden_space_id].set_space(young_gen->eden_space()); | |
884 _space_info[from_space_id].set_space(young_gen->from_space()); | |
885 _space_info[to_space_id].set_space(young_gen->to_space()); | |
886 | |
887 _space_info[perm_space_id].set_start_array(heap->perm_gen()->start_array()); | |
888 _space_info[old_space_id].set_start_array(heap->old_gen()->start_array()); | |
889 | |
890 _space_info[perm_space_id].set_min_dense_prefix(perm_space->top()); | |
891 if (TraceParallelOldGCDensePrefix) { | |
892 tty->print_cr("perm min_dense_prefix=" PTR_FORMAT, | |
893 _space_info[perm_space_id].min_dense_prefix()); | |
894 } | |
895 } | |
896 | |
897 void PSParallelCompact::initialize_dead_wood_limiter() | |
898 { | |
899 const size_t max = 100; | |
900 _dwl_mean = double(MIN2(ParallelOldDeadWoodLimiterMean, max)) / 100.0; | |
901 _dwl_std_dev = double(MIN2(ParallelOldDeadWoodLimiterStdDev, max)) / 100.0; | |
902 _dwl_first_term = 1.0 / (sqrt(2.0 * M_PI) * _dwl_std_dev); | |
903 DEBUG_ONLY(_dwl_initialized = true;) | |
904 _dwl_adjustment = normal_distribution(1.0); | |
905 } | |
906 | |
907 // Simple class for storing info about the heap at the start of GC, to be used | |
908 // after GC for comparison/printing. | |
909 class PreGCValues { | |
910 public: | |
911 PreGCValues() { } | |
912 PreGCValues(ParallelScavengeHeap* heap) { fill(heap); } | |
913 | |
914 void fill(ParallelScavengeHeap* heap) { | |
915 _heap_used = heap->used(); | |
916 _young_gen_used = heap->young_gen()->used_in_bytes(); | |
917 _old_gen_used = heap->old_gen()->used_in_bytes(); | |
918 _perm_gen_used = heap->perm_gen()->used_in_bytes(); | |
919 }; | |
920 | |
921 size_t heap_used() const { return _heap_used; } | |
922 size_t young_gen_used() const { return _young_gen_used; } | |
923 size_t old_gen_used() const { return _old_gen_used; } | |
924 size_t perm_gen_used() const { return _perm_gen_used; } | |
925 | |
926 private: | |
927 size_t _heap_used; | |
928 size_t _young_gen_used; | |
929 size_t _old_gen_used; | |
930 size_t _perm_gen_used; | |
931 }; | |
932 | |
933 void | |
934 PSParallelCompact::clear_data_covering_space(SpaceId id) | |
935 { | |
936 // At this point, top is the value before GC, new_top() is the value that will | |
937 // be set at the end of GC. The marking bitmap is cleared to top; nothing | |
938 // should be marked above top. The summary data is cleared to the larger of | |
939 // top & new_top. | |
940 MutableSpace* const space = _space_info[id].space(); | |
941 HeapWord* const bot = space->bottom(); | |
942 HeapWord* const top = space->top(); | |
943 HeapWord* const max_top = MAX2(top, _space_info[id].new_top()); | |
944 | |
945 const idx_t beg_bit = _mark_bitmap.addr_to_bit(bot); | |
946 const idx_t end_bit = BitMap::word_align_up(_mark_bitmap.addr_to_bit(top)); | |
947 _mark_bitmap.clear_range(beg_bit, end_bit); | |
948 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
949 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
|
950 const size_t end_region = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
951 _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
|
952 _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
|
953 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
954 // Clear the data used to 'split' regions. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
955 SplitInfo& split_info = _space_info[id].split_info(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
956 if (split_info.is_valid()) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
957 split_info.clear(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
958 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
959 DEBUG_ONLY(split_info.verify_clear();) |
0 | 960 } |
961 | |
962 void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values) | |
963 { | |
964 // Update the from & to space pointers in space_info, since they are swapped | |
965 // at each young gen gc. Do the update unconditionally (even though a | |
966 // promotion failure does not swap spaces) because an unknown number of minor | |
967 // collections will have swapped the spaces an unknown number of times. | |
968 TraceTime tm("pre compact", print_phases(), true, gclog_or_tty); | |
969 ParallelScavengeHeap* heap = gc_heap(); | |
970 _space_info[from_space_id].set_space(heap->young_gen()->from_space()); | |
971 _space_info[to_space_id].set_space(heap->young_gen()->to_space()); | |
972 | |
973 pre_gc_values->fill(heap); | |
974 | |
975 ParCompactionManager::reset(); | |
976 NOT_PRODUCT(_mark_bitmap.reset_counters()); | |
977 DEBUG_ONLY(add_obj_count = add_obj_size = 0;) | |
978 DEBUG_ONLY(mark_bitmap_count = mark_bitmap_size = 0;) | |
979 | |
980 // 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
|
981 heap->increment_total_collections(true); |
0 | 982 |
983 // We need to track unique mark sweep invocations as well. | |
984 _total_invocations++; | |
985 | |
986 if (PrintHeapAtGC) { | |
987 Universe::print_heap_before_gc(); | |
988 } | |
989 | |
990 // Fill in TLABs | |
991 heap->accumulate_statistics_all_tlabs(); | |
992 heap->ensure_parsability(true); // retire TLABs | |
993 | |
994 if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) { | |
995 HandleMark hm; // Discard invalid handles created during verification | |
996 gclog_or_tty->print(" VerifyBeforeGC:"); | |
997 Universe::verify(true); | |
998 } | |
999 | |
1000 // Verify object start arrays | |
1001 if (VerifyObjectStartArray && | |
1002 VerifyBeforeGC) { | |
1003 heap->old_gen()->verify_object_start_array(); | |
1004 heap->perm_gen()->verify_object_start_array(); | |
1005 } | |
1006 | |
1007 DEBUG_ONLY(mark_bitmap()->verify_clear();) | |
1008 DEBUG_ONLY(summary_data().verify_clear();) | |
210 | 1009 |
1010 // Have worker threads release resources the next time they run a task. | |
1011 gc_task_manager()->release_all_resources(); | |
0 | 1012 } |
1013 | |
1014 void PSParallelCompact::post_compact() | |
1015 { | |
1016 TraceTime tm("post compact", print_phases(), true, gclog_or_tty); | |
1017 | |
1018 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
|
1019 // Clear the marking bitmap, summary data and split info. |
0 | 1020 clear_data_covering_space(SpaceId(id)); |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1021 // 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
|
1022 _space_info[id].publish_new_top(); |
0 | 1023 } |
1024 | |
1025 MutableSpace* const eden_space = _space_info[eden_space_id].space(); | |
1026 MutableSpace* const from_space = _space_info[from_space_id].space(); | |
1027 MutableSpace* const to_space = _space_info[to_space_id].space(); | |
1028 | |
1029 ParallelScavengeHeap* heap = gc_heap(); | |
1030 bool eden_empty = eden_space->is_empty(); | |
1031 if (!eden_empty) { | |
1032 eden_empty = absorb_live_data_from_eden(heap->size_policy(), | |
1033 heap->young_gen(), heap->old_gen()); | |
1034 } | |
1035 | |
1036 // Update heap occupancy information which is used as input to the soft ref | |
1037 // clearing policy at the next gc. | |
1038 Universe::update_heap_info_at_gc(); | |
1039 | |
1040 bool young_gen_empty = eden_empty && from_space->is_empty() && | |
1041 to_space->is_empty(); | |
1042 | |
1043 BarrierSet* bs = heap->barrier_set(); | |
1044 if (bs->is_a(BarrierSet::ModRef)) { | |
1045 ModRefBarrierSet* modBS = (ModRefBarrierSet*)bs; | |
1046 MemRegion old_mr = heap->old_gen()->reserved(); | |
1047 MemRegion perm_mr = heap->perm_gen()->reserved(); | |
1048 assert(perm_mr.end() <= old_mr.start(), "Generations out of order"); | |
1049 | |
1050 if (young_gen_empty) { | |
1051 modBS->clear(MemRegion(perm_mr.start(), old_mr.end())); | |
1052 } else { | |
1053 modBS->invalidate(MemRegion(perm_mr.start(), old_mr.end())); | |
1054 } | |
1055 } | |
1056 | |
1057 Threads::gc_epilogue(); | |
1058 CodeCache::gc_epilogue(); | |
2147
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
1972
diff
changeset
|
1059 JvmtiExport::gc_epilogue(); |
0 | 1060 |
1061 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); | |
1062 | |
1063 ref_processor()->enqueue_discovered_references(NULL); | |
1064 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
1065 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
1066 heap->gen_mangle_unused_area(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
1067 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
1068 |
0 | 1069 // Update time of last GC |
1070 reset_millis_since_last_gc(); | |
1071 } | |
1072 | |
1073 HeapWord* | |
1074 PSParallelCompact::compute_dense_prefix_via_density(const SpaceId id, | |
1075 bool maximum_compaction) | |
1076 { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1077 const size_t region_size = ParallelCompactData::RegionSize; |
0 | 1078 const ParallelCompactData& sd = summary_data(); |
1079 | |
1080 const MutableSpace* const space = _space_info[id].space(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1081 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
|
1082 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
|
1083 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
|
1084 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1085 // Skip full regions at the beginning of the space--they are necessarily part |
0 | 1086 // of the dense prefix. |
1087 size_t full_count = 0; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1088 const RegionData* cp; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1089 for (cp = beg_cp; cp < end_cp && cp->data_size() == region_size; ++cp) { |
0 | 1090 ++full_count; |
1091 } | |
1092 | |
1093 assert(total_invocations() >= _maximum_compaction_gc_num, "sanity"); | |
1094 const size_t gcs_since_max = total_invocations() - _maximum_compaction_gc_num; | |
1095 const bool interval_ended = gcs_since_max > HeapMaximumCompactionInterval; | |
1096 if (maximum_compaction || cp == end_cp || interval_ended) { | |
1097 _maximum_compaction_gc_num = total_invocations(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1098 return sd.region_to_addr(cp); |
0 | 1099 } |
1100 | |
1101 HeapWord* const new_top = _space_info[id].new_top(); | |
1102 const size_t space_live = pointer_delta(new_top, space->bottom()); | |
1103 const size_t space_used = space->used_in_words(); | |
1104 const size_t space_capacity = space->capacity_in_words(); | |
1105 | |
1106 const double cur_density = double(space_live) / space_capacity; | |
1107 const double deadwood_density = | |
1108 (1.0 - cur_density) * (1.0 - cur_density) * cur_density * cur_density; | |
1109 const size_t deadwood_goal = size_t(space_capacity * deadwood_density); | |
1110 | |
1111 if (TraceParallelOldGCDensePrefix) { | |
1112 tty->print_cr("cur_dens=%5.3f dw_dens=%5.3f dw_goal=" SIZE_FORMAT, | |
1113 cur_density, deadwood_density, deadwood_goal); | |
1114 tty->print_cr("space_live=" SIZE_FORMAT " " "space_used=" SIZE_FORMAT " " | |
1115 "space_cap=" SIZE_FORMAT, | |
1116 space_live, space_used, | |
1117 space_capacity); | |
1118 } | |
1119 | |
1120 // XXX - Use binary search? | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1121 HeapWord* dense_prefix = sd.region_to_addr(cp); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1122 const RegionData* full_cp = cp; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1123 const RegionData* const top_cp = sd.addr_to_region_ptr(space->top() - 1); |
0 | 1124 while (cp < end_cp) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1125 HeapWord* region_destination = cp->destination(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1126 const size_t cur_deadwood = pointer_delta(dense_prefix, region_destination); |
0 | 1127 if (TraceParallelOldGCDensePrefix && Verbose) { |
264
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
1128 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
|
1129 "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
|
1130 sd.region(cp), region_destination, |
0 | 1131 dense_prefix, cur_deadwood); |
1132 } | |
1133 | |
1134 if (cur_deadwood >= deadwood_goal) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1135 // 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
|
1136 // 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
|
1137 // iterate backwards over those sparse regions, looking for the region |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1138 // 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
|
1139 size_t space_to_left = sd.region(cp) * region_size; |
0 | 1140 size_t live_to_left = space_to_left - cur_deadwood; |
1141 size_t space_to_right = space_capacity - space_to_left; | |
1142 size_t live_to_right = space_live - live_to_left; | |
1143 double density_to_right = double(live_to_right) / space_to_right; | |
1144 while (cp > full_cp) { | |
1145 --cp; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1146 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
|
1147 cp->data_size(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1148 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
|
1149 double prev_region_density_to_right = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1150 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
|
1151 if (density_to_right <= prev_region_density_to_right) { |
0 | 1152 return dense_prefix; |
1153 } | |
1154 if (TraceParallelOldGCDensePrefix && Verbose) { | |
264
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
1155 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
|
1156 "pc_d2r=%10.8f", sd.region(cp), density_to_right, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1157 prev_region_density_to_right); |
0 | 1158 } |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1159 dense_prefix -= region_size; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1160 live_to_right = prev_region_live_to_right; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1161 space_to_right = prev_region_space_to_right; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1162 density_to_right = prev_region_density_to_right; |
0 | 1163 } |
1164 return dense_prefix; | |
1165 } | |
1166 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1167 dense_prefix += region_size; |
0 | 1168 ++cp; |
1169 } | |
1170 | |
1171 return dense_prefix; | |
1172 } | |
1173 | |
1174 #ifndef PRODUCT | |
1175 void PSParallelCompact::print_dense_prefix_stats(const char* const algorithm, | |
1176 const SpaceId id, | |
1177 const bool maximum_compaction, | |
1178 HeapWord* const addr) | |
1179 { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1180 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
|
1181 RegionData* const cp = summary_data().region(region_idx); |
0 | 1182 const MutableSpace* const space = _space_info[id].space(); |
1183 HeapWord* const new_top = _space_info[id].new_top(); | |
1184 | |
1185 const size_t space_live = pointer_delta(new_top, space->bottom()); | |
1186 const size_t dead_to_left = pointer_delta(addr, cp->destination()); | |
1187 const size_t space_cap = space->capacity_in_words(); | |
1188 const double dead_to_left_pct = double(dead_to_left) / space_cap; | |
1189 const size_t live_to_right = new_top - cp->destination(); | |
1190 const size_t dead_to_right = space->top() - addr - live_to_right; | |
1191 | |
264
15dd2594d08e
6718283: existing uses of *_FORMAT_W() were broken by 6521491
jcoomes
parents:
263
diff
changeset
|
1192 tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W(5) " " |
0 | 1193 "spl=" SIZE_FORMAT " " |
1194 "d2l=" SIZE_FORMAT " d2l%%=%6.4f " | |
1195 "d2r=" SIZE_FORMAT " l2r=" SIZE_FORMAT | |
1196 " ratio=%10.8f", | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1197 algorithm, addr, region_idx, |
0 | 1198 space_live, |
1199 dead_to_left, dead_to_left_pct, | |
1200 dead_to_right, live_to_right, | |
1201 double(dead_to_right) / live_to_right); | |
1202 } | |
1203 #endif // #ifndef PRODUCT | |
1204 | |
1205 // Return a fraction indicating how much of the generation can be treated as | |
1206 // "dead wood" (i.e., not reclaimed). The function uses a normal distribution | |
1207 // based on the density of live objects in the generation to determine a limit, | |
1208 // which is then adjusted so the return value is min_percent when the density is | |
1209 // 1. | |
1210 // | |
1211 // The following table shows some return values for a different values of the | |
1212 // standard deviation (ParallelOldDeadWoodLimiterStdDev); the mean is 0.5 and | |
1213 // min_percent is 1. | |
1214 // | |
1215 // fraction allowed as dead wood | |
1216 // ----------------------------------------------------------------- | |
1217 // density std_dev=70 std_dev=75 std_dev=80 std_dev=85 std_dev=90 std_dev=95 | |
1218 // ------- ---------- ---------- ---------- ---------- ---------- ---------- | |
1219 // 0.00000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 | |
1220 // 0.05000 0.03193096 0.02836880 0.02550828 0.02319280 0.02130337 0.01974941 | |
1221 // 0.10000 0.05247504 0.04547452 0.03988045 0.03537016 0.03170171 0.02869272 | |
1222 // 0.15000 0.07135702 0.06111390 0.05296419 0.04641639 0.04110601 0.03676066 | |
1223 // 0.20000 0.08831616 0.07509618 0.06461766 0.05622444 0.04943437 0.04388975 | |
1224 // 0.25000 0.10311208 0.08724696 0.07471205 0.06469760 0.05661313 0.05002313 | |
1225 // 0.30000 0.11553050 0.09741183 0.08313394 0.07175114 0.06257797 0.05511132 | |
1226 // 0.35000 0.12538832 0.10545958 0.08978741 0.07731366 0.06727491 0.05911289 | |
1227 // 0.40000 0.13253818 0.11128511 0.09459590 0.08132834 0.07066107 0.06199500 | |
1228 // 0.45000 0.13687208 0.11481163 0.09750361 0.08375387 0.07270534 0.06373386 | |
1229 // 0.50000 0.13832410 0.11599237 0.09847664 0.08456518 0.07338887 0.06431510 | |
1230 // 0.55000 0.13687208 0.11481163 0.09750361 0.08375387 0.07270534 0.06373386 | |
1231 // 0.60000 0.13253818 0.11128511 0.09459590 0.08132834 0.07066107 0.06199500 | |
1232 // 0.65000 0.12538832 0.10545958 0.08978741 0.07731366 0.06727491 0.05911289 | |
1233 // 0.70000 0.11553050 0.09741183 0.08313394 0.07175114 0.06257797 0.05511132 | |
1234 // 0.75000 0.10311208 0.08724696 0.07471205 0.06469760 0.05661313 0.05002313 | |
1235 // 0.80000 0.08831616 0.07509618 0.06461766 0.05622444 0.04943437 0.04388975 | |
1236 // 0.85000 0.07135702 0.06111390 0.05296419 0.04641639 0.04110601 0.03676066 | |
1237 // 0.90000 0.05247504 0.04547452 0.03988045 0.03537016 0.03170171 0.02869272 | |
1238 // 0.95000 0.03193096 0.02836880 0.02550828 0.02319280 0.02130337 0.01974941 | |
1239 // 1.00000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 | |
1240 | |
1241 double PSParallelCompact::dead_wood_limiter(double density, size_t min_percent) | |
1242 { | |
1243 assert(_dwl_initialized, "uninitialized"); | |
1244 | |
1245 // The raw limit is the value of the normal distribution at x = density. | |
1246 const double raw_limit = normal_distribution(density); | |
1247 | |
1248 // Adjust the raw limit so it becomes the minimum when the density is 1. | |
1249 // | |
1250 // First subtract the adjustment value (which is simply the precomputed value | |
1251 // normal_distribution(1.0)); this yields a value of 0 when the density is 1. | |
1252 // Then add the minimum value, so the minimum is returned when the density is | |
1253 // 1. Finally, prevent negative values, which occur when the mean is not 0.5. | |
1254 const double min = double(min_percent) / 100.0; | |
1255 const double limit = raw_limit - _dwl_adjustment + min; | |
1256 return MAX2(limit, 0.0); | |
1257 } | |
1258 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1259 ParallelCompactData::RegionData* |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1260 PSParallelCompact::first_dead_space_region(const RegionData* beg, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1261 const RegionData* end) |
0 | 1262 { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1263 const size_t region_size = ParallelCompactData::RegionSize; |
0 | 1264 ParallelCompactData& sd = summary_data(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1265 size_t left = sd.region(beg); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1266 size_t right = end > beg ? sd.region(end) - 1 : left; |
0 | 1267 |
1268 // Binary search. | |
1269 while (left < right) { | |
1270 // Equivalent to (left + right) / 2, but does not overflow. | |
1271 const size_t middle = left + (right - left) / 2; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1272 RegionData* const middle_ptr = sd.region(middle); |
0 | 1273 HeapWord* const dest = middle_ptr->destination(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1274 HeapWord* const addr = sd.region_to_addr(middle); |
0 | 1275 assert(dest != NULL, "sanity"); |
1276 assert(dest <= addr, "must move left"); | |
1277 | |
1278 if (middle > left && dest < addr) { | |
1279 right = middle - 1; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1280 } else if (middle < right && middle_ptr->data_size() == region_size) { |
0 | 1281 left = middle + 1; |
1282 } else { | |
1283 return middle_ptr; | |
1284 } | |
1285 } | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1286 return sd.region(left); |
0 | 1287 } |
1288 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1289 ParallelCompactData::RegionData* |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1290 PSParallelCompact::dead_wood_limit_region(const RegionData* beg, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1291 const RegionData* end, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1292 size_t dead_words) |
0 | 1293 { |
1294 ParallelCompactData& sd = summary_data(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1295 size_t left = sd.region(beg); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1296 size_t right = end > beg ? sd.region(end) - 1 : left; |
0 | 1297 |
1298 // Binary search. | |
1299 while (left < right) { | |
1300 // Equivalent to (left + right) / 2, but does not overflow. | |
1301 const size_t middle = left + (right - left) / 2; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1302 RegionData* const middle_ptr = sd.region(middle); |
0 | 1303 HeapWord* const dest = middle_ptr->destination(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1304 HeapWord* const addr = sd.region_to_addr(middle); |
0 | 1305 assert(dest != NULL, "sanity"); |
1306 assert(dest <= addr, "must move left"); | |
1307 | |
1308 const size_t dead_to_left = pointer_delta(addr, dest); | |
1309 if (middle > left && dead_to_left > dead_words) { | |
1310 right = middle - 1; | |
1311 } else if (middle < right && dead_to_left < dead_words) { | |
1312 left = middle + 1; | |
1313 } else { | |
1314 return middle_ptr; | |
1315 } | |
1316 } | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1317 return sd.region(left); |
0 | 1318 } |
1319 | |
1320 // The result is valid during the summary phase, after the initial summarization | |
1321 // of each space into itself, and before final summarization. | |
1322 inline double | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1323 PSParallelCompact::reclaimed_ratio(const RegionData* const cp, |
0 | 1324 HeapWord* const bottom, |
1325 HeapWord* const top, | |
1326 HeapWord* const new_top) | |
1327 { | |
1328 ParallelCompactData& sd = summary_data(); | |
1329 | |
1330 assert(cp != NULL, "sanity"); | |
1331 assert(bottom != NULL, "sanity"); | |
1332 assert(top != NULL, "sanity"); | |
1333 assert(new_top != NULL, "sanity"); | |
1334 assert(top >= new_top, "summary data problem?"); | |
1335 assert(new_top > bottom, "space is empty; should not be here"); | |
1336 assert(new_top >= cp->destination(), "sanity"); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1337 assert(top >= sd.region_to_addr(cp), "sanity"); |
0 | 1338 |
1339 HeapWord* const destination = cp->destination(); | |
1340 const size_t dense_prefix_live = pointer_delta(destination, bottom); | |
1341 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
|
1342 const size_t compacted_region_used = pointer_delta(top, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1343 sd.region_to_addr(cp)); |
0 | 1344 const size_t reclaimable = compacted_region_used - compacted_region_live; |
1345 | |
1346 const double divisor = dense_prefix_live + 1.25 * compacted_region_live; | |
1347 return double(reclaimable) / divisor; | |
1348 } | |
1349 | |
1350 // 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
|
1351 // compacted region. The address is always on a region boundary. |
0 | 1352 // |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1353 // 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
|
1354 // 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
|
1355 // 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
|
1356 // 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
|
1357 // 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
|
1358 // 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
|
1359 // (maximum) reclaimed_ratio() is selected. |
0 | 1360 HeapWord* |
1361 PSParallelCompact::compute_dense_prefix(const SpaceId id, | |
1362 bool maximum_compaction) | |
1363 { | |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1364 if (ParallelOldGCSplitALot) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1365 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
|
1366 // 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
|
1367 return _space_info[id].dense_prefix(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1368 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1369 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1370 |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1371 const size_t region_size = ParallelCompactData::RegionSize; |
0 | 1372 const ParallelCompactData& sd = summary_data(); |
1373 | |
1374 const MutableSpace* const space = _space_info[id].space(); | |
1375 HeapWord* const top = space->top(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1376 HeapWord* const top_aligned_up = sd.region_align_up(top); |
0 | 1377 HeapWord* const new_top = _space_info[id].new_top(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1378 HeapWord* const new_top_aligned_up = sd.region_align_up(new_top); |
0 | 1379 HeapWord* const bottom = space->bottom(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1380 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
|
1381 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
|
1382 const RegionData* const new_top_cp = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1383 sd.addr_to_region_ptr(new_top_aligned_up); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1384 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1385 // Skip full regions at the beginning of the space--they are necessarily part |
0 | 1386 // of the dense prefix. |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1387 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
|
1388 assert(full_cp->destination() == sd.region_to_addr(full_cp) || |
0 | 1389 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
|
1390 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
|
1391 "region must have dead space"); |
0 | 1392 |
1393 // The gc number is saved whenever a maximum compaction is done, and used to | |
1394 // determine when the maximum compaction interval has expired. This avoids | |
1395 // successive max compactions for different reasons. | |
1396 assert(total_invocations() >= _maximum_compaction_gc_num, "sanity"); | |
1397 const size_t gcs_since_max = total_invocations() - _maximum_compaction_gc_num; | |
1398 const bool interval_ended = gcs_since_max > HeapMaximumCompactionInterval || | |
1399 total_invocations() == HeapFirstMaximumCompactionCount; | |
1400 if (maximum_compaction || full_cp == top_cp || interval_ended) { | |
1401 _maximum_compaction_gc_num = total_invocations(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1402 return sd.region_to_addr(full_cp); |
0 | 1403 } |
1404 | |
1405 const size_t space_live = pointer_delta(new_top, bottom); | |
1406 const size_t space_used = space->used_in_words(); | |
1407 const size_t space_capacity = space->capacity_in_words(); | |
1408 | |
1409 const double density = double(space_live) / double(space_capacity); | |
1410 const size_t min_percent_free = | |
1411 id == perm_space_id ? PermMarkSweepDeadRatio : MarkSweepDeadRatio; | |
1412 const double limiter = dead_wood_limiter(density, min_percent_free); | |
1413 const size_t dead_wood_max = space_used - space_live; | |
1414 const size_t dead_wood_limit = MIN2(size_t(space_capacity * limiter), | |
1415 dead_wood_max); | |
1416 | |
1417 if (TraceParallelOldGCDensePrefix) { | |
1418 tty->print_cr("space_live=" SIZE_FORMAT " " "space_used=" SIZE_FORMAT " " | |
1419 "space_cap=" SIZE_FORMAT, | |
1420 space_live, space_used, | |
1421 space_capacity); | |
1422 tty->print_cr("dead_wood_limiter(%6.4f, %d)=%6.4f " | |
1423 "dead_wood_max=" SIZE_FORMAT " dead_wood_limit=" SIZE_FORMAT, | |
1424 density, min_percent_free, limiter, | |
1425 dead_wood_max, dead_wood_limit); | |
1426 } | |
1427 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1428 // 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
|
1429 const RegionData* const limit_cp = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1430 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
|
1431 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1432 // Scan from the first region with dead space to the limit region and find the |
0 | 1433 // one with the best (largest) reclaimed ratio. |
1434 double best_ratio = 0.0; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1435 const RegionData* best_cp = full_cp; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1436 for (const RegionData* cp = full_cp; cp < limit_cp; ++cp) { |
0 | 1437 double tmp_ratio = reclaimed_ratio(cp, bottom, top, new_top); |
1438 if (tmp_ratio > best_ratio) { | |
1439 best_cp = cp; | |
1440 best_ratio = tmp_ratio; | |
1441 } | |
1442 } | |
1443 | |
1444 #if 0 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1445 // 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
|
1446 // 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
|
1447 // ("first-free"). The first-free region is usually near the start of the |
0 | 1448 // heap, which means we are copying most of the heap already, so copy a bit |
1449 // more to get complete compaction. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1450 if (pointer_delta(best_cp, full_cp, sizeof(RegionData)) < 4) { |
0 | 1451 _maximum_compaction_gc_num = total_invocations(); |
1452 best_cp = full_cp; | |
1453 } | |
1454 #endif // #if 0 | |
1455 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1456 return sd.region_to_addr(best_cp); |
0 | 1457 } |
1458 | |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1459 #ifndef PRODUCT |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1460 void |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1461 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
|
1462 size_t words) |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1463 { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1464 if (TraceParallelOldGCSummaryPhase) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1465 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
|
1466 SIZE_FORMAT, start, start + words, words); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1467 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1468 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1469 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
|
1470 CollectedHeap::fill_with_objects(start, words); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1471 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
|
1472 _mark_bitmap.mark_obj(p, words); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1473 _summary_data.add_obj(p, words); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1474 start_array->allocate_block(p); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1475 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1476 } |
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 void |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1479 PSParallelCompact::summarize_new_objects(SpaceId id, HeapWord* start) |
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 ParallelCompactData& sd = summary_data(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1482 MutableSpace* space = _space_info[id].space(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1483 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1484 // Find the source and destination start addresses. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1485 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
|
1486 HeapWord* dst_addr; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1487 if (src_addr < start) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1488 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
|
1489 } else if (src_addr > space->bottom()) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1490 // 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
|
1491 // 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
|
1492 // destination from the previous region. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1493 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
|
1494 dst_addr = cp->destination() + cp->data_size(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1495 } else { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1496 // Filling the entire space. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1497 dst_addr = space->bottom(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1498 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1499 assert(dst_addr != NULL, "sanity"); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1500 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1501 // Update the summary data. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1502 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
|
1503 src_addr, space->top(), NULL, |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1504 dst_addr, space->end(), |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1505 _space_info[id].new_top_addr()); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1506 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
|
1507 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1508 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1509 void |
496
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1510 PSParallelCompact::provoke_split_fill_survivor(SpaceId id) |
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 if (total_invocations() % (ParallelOldGCSplitInterval * 3) != 0) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1513 return; |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1514 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1515 |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1516 MutableSpace* const space = _space_info[id].space(); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1517 if (space->is_empty()) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1518 HeapWord* b = space->bottom(); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1519 HeapWord* t = b + space->capacity_in_words() / 2; |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1520 space->set_top(t); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1521 if (ZapUnusedHeapArea) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1522 space->set_top_for_allocations(); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1523 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1524 |
1571
2d127394260e
6916623: Align object to 16 bytes to use Compressed Oops with java heap up to 64Gb
kvn
parents:
1489
diff
changeset
|
1525 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
|
1526 size_t obj_len = min_size; |
496
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1527 while (b + obj_len <= t) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1528 CollectedHeap::fill_with_object(b, obj_len); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1529 mark_bitmap()->mark_obj(b, obj_len); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1530 summary_data().add_obj(b, obj_len); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1531 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
|
1532 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
|
1533 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1534 if (b < t) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1535 // 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
|
1536 space->set_top(b); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1537 if (ZapUnusedHeapArea) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1538 space->set_top_for_allocations(); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1539 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1540 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1541 |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1542 HeapWord** nta = _space_info[id].new_top_addr(); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1543 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
|
1544 space->bottom(), space->top(), NULL, |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1545 space->bottom(), space->end(), nta); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1546 assert(result, "space must fit into itself"); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1547 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1548 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1549 |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1550 void |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1551 PSParallelCompact::provoke_split(bool & max_compaction) |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1552 { |
496
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1553 if (total_invocations() % ParallelOldGCSplitInterval != 0) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1554 return; |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1555 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1556 |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1557 const size_t region_size = ParallelCompactData::RegionSize; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1558 ParallelCompactData& sd = summary_data(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1559 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1560 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
|
1561 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
|
1562 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
|
1563 _space_info[eden_space_id].new_top()); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1564 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
|
1565 _space_info[from_space_id].new_top()); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1566 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1567 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
|
1568 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
|
1569 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
|
1570 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
|
1571 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
|
1572 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1573 // 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
|
1574 SpaceId id; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1575 MutableSpace* space; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1576 size_t live_words; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1577 size_t fill_words; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1578 if (eden_live + eden_fillable >= region_size * 2) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1579 id = eden_space_id; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1580 space = eden_space; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1581 live_words = eden_live; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1582 fill_words = eden_fillable; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1583 } 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
|
1584 id = from_space_id; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1585 space = from_space; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1586 live_words = from_live; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1587 fill_words = from_fillable; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1588 } else { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1589 return; // Give up. |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1590 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1591 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
|
1592 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1593 if (live_words < region_size * 2) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1594 // 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
|
1595 HeapWord* const fill_start = space->top(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1596 live_words += fill_words; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1597 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1598 space->set_top(fill_start + fill_words); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1599 if (ZapUnusedHeapArea) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1600 space->set_top_for_allocations(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1601 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1602 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1603 HeapWord* cur_addr = fill_start; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1604 while (fill_words > 0) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1605 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
|
1606 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
|
1607 if (fill_words - cur_size < min_fill_size) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1608 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
|
1609 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1610 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1611 CollectedHeap::fill_with_object(cur_addr, cur_size); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1612 mark_bitmap()->mark_obj(cur_addr, cur_size); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1613 sd.add_obj(cur_addr, 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 cur_addr += cur_size; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1616 fill_words -= cur_size; |
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 summarize_new_objects(id, fill_start); |
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 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1622 max_compaction = false; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1623 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1624 // 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
|
1625 // 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
|
1626 id = old_space_id; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1627 space = _space_info[id].space(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1628 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
|
1629 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
|
1630 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
|
1631 |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1632 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
|
1633 // 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
|
1634 HeapWord* const fill_start = space->top(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1635 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
|
1636 space->set_top(space->top() + fill_size); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1637 if (ZapUnusedHeapArea) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1638 space->set_top_for_allocations(); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1639 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1640 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
|
1641 summarize_new_objects(id, fill_start); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1642 _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
|
1643 } else if (dead + free_at_end > free_target) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1644 // 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
|
1645 HeapWord* cur = sd.region_align_down(space->top()); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1646 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
|
1647 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
|
1648 while (dead_to_right < free_target) { |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1649 cur -= region_size; |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1650 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
|
1651 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
|
1652 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1653 _space_info[id].set_dense_prefix(cur); |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1654 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1655 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1656 #endif // #ifndef PRODUCT |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1657 |
0 | 1658 void PSParallelCompact::summarize_spaces_quick() |
1659 { | |
1660 for (unsigned int i = 0; i < last_space_id; ++i) { | |
1661 const MutableSpace* space = _space_info[i].space(); | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1662 HeapWord** nta = _space_info[i].new_top_addr(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1663 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
|
1664 space->bottom(), space->top(), NULL, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1665 space->bottom(), space->end(), nta); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1666 assert(result, "space must fit into itself"); |
0 | 1667 _space_info[i].set_dense_prefix(space->bottom()); |
1668 } | |
496
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1669 |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1670 #ifndef PRODUCT |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1671 if (ParallelOldGCSplitALot) { |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1672 provoke_split_fill_survivor(to_space_id); |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1673 } |
b27c885f75f9
6786188: par compact - "SplitALot" stress mode should fill to_space
jcoomes
parents:
495
diff
changeset
|
1674 #endif // #ifndef PRODUCT |
0 | 1675 } |
1676 | |
1677 void PSParallelCompact::fill_dense_prefix_end(SpaceId id) | |
1678 { | |
1679 HeapWord* const dense_prefix_end = dense_prefix(id); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1680 const RegionData* region = _summary_data.addr_to_region_ptr(dense_prefix_end); |
0 | 1681 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
|
1682 if (dead_space_crosses_boundary(region, dense_prefix_bit)) { |
0 | 1683 // Only enough dead space is filled so that any remaining dead space to the |
1684 // left is larger than the minimum filler object. (The remainder is filled | |
1685 // during the copy/update phase.) | |
1686 // | |
1687 // The size of the dead space to the right of the boundary is not a | |
1688 // concern, since compaction will be able to use whatever space is | |
1689 // available. | |
1690 // | |
1691 // Here '||' is the boundary, 'x' represents a don't care bit and a box | |
1692 // surrounds the space to be filled with an object. | |
1693 // | |
1694 // In the 32-bit VM, each bit represents two 32-bit words: | |
1695 // +---+ | |
1696 // a) beg_bits: ... x x x | 0 | || 0 x x ... | |
1697 // end_bits: ... x x x | 0 | || 0 x x ... | |
1698 // +---+ | |
1699 // | |
1700 // In the 64-bit VM, each bit represents one 64-bit word: | |
1701 // +------------+ | |
1702 // b) beg_bits: ... x x x | 0 || 0 | x x ... | |
1703 // end_bits: ... x x 1 | 0 || 0 | x x ... | |
1704 // +------------+ | |
1705 // +-------+ | |
1706 // c) beg_bits: ... x x | 0 0 | || 0 x x ... | |
1707 // end_bits: ... x 1 | 0 0 | || 0 x x ... | |
1708 // +-------+ | |
1709 // +-----------+ | |
1710 // d) beg_bits: ... x | 0 0 0 | || 0 x x ... | |
1711 // end_bits: ... 1 | 0 0 0 | || 0 x x ... | |
1712 // +-----------+ | |
1713 // +-------+ | |
1714 // e) beg_bits: ... 0 0 | 0 0 | || 0 x x ... | |
1715 // end_bits: ... 0 0 | 0 0 | || 0 x x ... | |
1716 // +-------+ | |
1717 | |
1718 // 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
|
1719 size_t obj_len = CollectedHeap::min_fill_size(); |
0 | 1720 HeapWord* obj_beg = dense_prefix_end - obj_len; |
1721 | |
1722 #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
|
1723 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
|
1724 // 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
|
1725 } else if (_mark_bitmap.is_obj_end(dense_prefix_bit - 2)) { |
0 | 1726 // Case b above. |
1727 obj_beg = dense_prefix_end - 1; | |
1728 } else if (!_mark_bitmap.is_obj_end(dense_prefix_bit - 3) && | |
1729 _mark_bitmap.is_obj_end(dense_prefix_bit - 4)) { | |
1730 // Case d above. | |
1731 obj_beg = dense_prefix_end - 3; | |
1732 obj_len = 3; | |
1733 } | |
1734 #endif // #ifdef _LP64 | |
1735 | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1736 CollectedHeap::fill_with_object(obj_beg, obj_len); |
0 | 1737 _mark_bitmap.mark_obj(obj_beg, obj_len); |
1738 _summary_data.add_obj(obj_beg, obj_len); | |
1739 assert(start_array(id) != NULL, "sanity"); | |
1740 start_array(id)->allocate_block(obj_beg); | |
1741 } | |
1742 } | |
1743 | |
1744 void | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1745 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
|
1746 { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1747 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
|
1748 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
|
1749 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
|
1750 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
|
1751 cur->set_source_region(0); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1752 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1753 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1754 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1755 void |
0 | 1756 PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction) |
1757 { | |
1758 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
|
1759 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
|
1760 ParallelOldGCSplitALot && id == old_space_id, |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1761 "should have been reset in summarize_spaces_quick()"); |
0 | 1762 |
1763 const MutableSpace* space = _space_info[id].space(); | |
265
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1764 if (_space_info[id].new_top() != space->bottom()) { |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1765 HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction); |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1766 _space_info[id].set_dense_prefix(dense_prefix_end); |
0 | 1767 |
1768 #ifndef PRODUCT | |
265
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1769 if (TraceParallelOldGCDensePrefix) { |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1770 print_dense_prefix_stats("ratio", id, maximum_compaction, |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1771 dense_prefix_end); |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1772 HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction); |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1773 print_dense_prefix_stats("density", id, maximum_compaction, addr); |
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1774 } |
0 | 1775 #endif // #ifndef PRODUCT |
1776 | |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1777 // 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
|
1778 // 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
|
1779 // compacts everything can be left in place. |
265
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1780 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
|
1781 // 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
|
1782 // 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
|
1783 // 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
|
1784 // 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
|
1785 // 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
|
1786 fill_dense_prefix_end(id); |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1787 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1788 // 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
|
1789 _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
|
1790 _summary_data.summarize(_space_info[id].split_info(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1791 dense_prefix_end, space->top(), NULL, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1792 dense_prefix_end, space->end(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1793 _space_info[id].new_top_addr()); |
265
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1794 } |
0 | 1795 } |
1796 | |
1797 if (TraceParallelOldGCSummaryPhase) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1798 const size_t region_size = ParallelCompactData::RegionSize; |
265
f88815ca1af1
6483129: par compact assertion failure (new_top > bottom)
jcoomes
parents:
264
diff
changeset
|
1799 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
|
1800 const size_t dp_region = _summary_data.addr_to_region_idx(dense_prefix_end); |
0 | 1801 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
|
1802 HeapWord* const new_top = _space_info[id].new_top(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1803 const HeapWord* nt_aligned_up = _summary_data.region_align_up(new_top); |
0 | 1804 const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end); |
1805 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
|
1806 "dp_region=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " " |
0 | 1807 "cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT, |
1808 id, space->capacity_in_words(), dense_prefix_end, | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1809 dp_region, dp_words / region_size, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1810 cr_words / region_size, new_top); |
0 | 1811 } |
1812 } | |
1813 | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1814 #ifndef PRODUCT |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1815 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
|
1816 HeapWord* dst_beg, HeapWord* dst_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1817 SpaceId src_space_id, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1818 HeapWord* src_beg, HeapWord* src_end) |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1819 { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1820 if (TraceParallelOldGCSummaryPhase) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1821 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
|
1822 "src=" PTR_FORMAT "-" PTR_FORMAT " " |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1823 SIZE_FORMAT "-" SIZE_FORMAT " " |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1824 "dst=" PTR_FORMAT "-" PTR_FORMAT " " |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1825 SIZE_FORMAT "-" SIZE_FORMAT, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1826 src_space_id, space_names[src_space_id], |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1827 dst_space_id, space_names[dst_space_id], |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1828 src_beg, src_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1829 _summary_data.addr_to_region_idx(src_beg), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1830 _summary_data.addr_to_region_idx(src_end), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1831 dst_beg, dst_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1832 _summary_data.addr_to_region_idx(dst_beg), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1833 _summary_data.addr_to_region_idx(dst_end)); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1834 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1835 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1836 #endif // #ifndef PRODUCT |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1837 |
0 | 1838 void PSParallelCompact::summary_phase(ParCompactionManager* cm, |
1839 bool maximum_compaction) | |
1840 { | |
1841 EventMark m("2 summarize"); | |
1842 TraceTime tm("summary phase", print_phases(), true, gclog_or_tty); | |
1843 // trace("2"); | |
1844 | |
1845 #ifdef ASSERT | |
1846 if (TraceParallelOldGCMarkingPhase) { | |
1847 tty->print_cr("add_obj_count=" SIZE_FORMAT " " | |
1848 "add_obj_bytes=" SIZE_FORMAT, | |
1849 add_obj_count, add_obj_size * HeapWordSize); | |
1850 tty->print_cr("mark_bitmap_count=" SIZE_FORMAT " " | |
1851 "mark_bitmap_bytes=" SIZE_FORMAT, | |
1852 mark_bitmap_count, mark_bitmap_size * HeapWordSize); | |
1853 } | |
1854 #endif // #ifdef ASSERT | |
1855 | |
1856 // Quick summarization of each space into itself, to see how much is live. | |
1857 summarize_spaces_quick(); | |
1858 | |
1859 if (TraceParallelOldGCSummaryPhase) { | |
1860 tty->print_cr("summary_phase: after summarizing each space to self"); | |
1861 Universe::print(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1862 NOT_PRODUCT(print_region_ranges()); |
0 | 1863 if (Verbose) { |
1864 NOT_PRODUCT(print_initial_summary_data(_summary_data, _space_info)); | |
1865 } | |
1866 } | |
1867 | |
1868 // The amount of live data that will end up in old space (assuming it fits). | |
1869 size_t old_space_total_live = 0; | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1870 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
|
1871 for (unsigned int id = old_space_id; id < last_space_id; ++id) { |
0 | 1872 old_space_total_live += pointer_delta(_space_info[id].new_top(), |
1873 _space_info[id].space()->bottom()); | |
1874 } | |
1875 | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1876 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
|
1877 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
|
1878 if (old_space_total_live > old_capacity) { |
0 | 1879 // XXX - should also try to expand |
1880 maximum_compaction = true; | |
1881 } | |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1882 #ifndef PRODUCT |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1883 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
|
1884 provoke_split(maximum_compaction); |
483
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1885 } |
0f773163217d
6765954: par compact - stress mode for splitting young gen spaces
jcoomes
parents:
482
diff
changeset
|
1886 #endif // #ifndef PRODUCT |
0 | 1887 |
1888 // Permanent and Old generations. | |
1889 summarize_space(perm_space_id, maximum_compaction); | |
1890 summarize_space(old_space_id, maximum_compaction); | |
1891 | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1892 // 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
|
1893 // 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
|
1894 // 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
|
1895 // target. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1896 SpaceId dst_space_id = old_space_id; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1897 HeapWord* dst_space_end = old_space->end(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1898 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
|
1899 for (unsigned int id = eden_space_id; id < last_space_id; ++id) { |
0 | 1900 const MutableSpace* space = _space_info[id].space(); |
1901 const size_t live = pointer_delta(_space_info[id].new_top(), | |
1902 space->bottom()); | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1903 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
|
1904 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1905 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
|
1906 SpaceId(id), space->bottom(), space->top());) |
266
2214b226b7f0
6724367: par compact could clear less young gen summary data
jcoomes
parents:
265
diff
changeset
|
1907 if (live > 0 && live <= available) { |
0 | 1908 // All the live data will fit. |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1909 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
|
1910 space->bottom(), space->top(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1911 NULL, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1912 *new_top_addr, dst_space_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1913 new_top_addr); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1914 assert(done, "space must fit into old gen"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1915 |
266
2214b226b7f0
6724367: par compact could clear less young gen summary data
jcoomes
parents:
265
diff
changeset
|
1916 // Reset the new_top value for the space. |
2214b226b7f0
6724367: par compact could clear less young gen summary data
jcoomes
parents:
265
diff
changeset
|
1917 _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
|
1918 } else if (live > 0) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1919 // 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
|
1920 HeapWord* next_src_addr = NULL; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1921 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
|
1922 space->bottom(), space->top(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1923 &next_src_addr, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1924 *new_top_addr, dst_space_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1925 new_top_addr); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1926 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
|
1927 assert(next_src_addr != NULL, "sanity"); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1928 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1929 // 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
|
1930 // within the space itself. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1931 dst_space_id = SpaceId(id); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1932 dst_space_end = space->end(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1933 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
|
1934 NOT_PRODUCT(summary_phase_msg(dst_space_id, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1935 space->bottom(), dst_space_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1936 SpaceId(id), next_src_addr, space->top());) |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1937 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
|
1938 next_src_addr, space->top(), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1939 NULL, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1940 space->bottom(), dst_space_end, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1941 new_top_addr); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
1942 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
|
1943 assert(*new_top_addr <= space->top(), "usage should not grow"); |
0 | 1944 } |
1945 } | |
1946 | |
1947 if (TraceParallelOldGCSummaryPhase) { | |
1948 tty->print_cr("summary_phase: after final summarization"); | |
1949 Universe::print(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1950 NOT_PRODUCT(print_region_ranges()); |
0 | 1951 if (Verbose) { |
1952 NOT_PRODUCT(print_generic_summary_data(_summary_data, _space_info)); | |
1953 } | |
1954 } | |
1955 } | |
1956 | |
1957 // This method should contain all heap-specific policy for invoking a full | |
1958 // collection. invoke_no_policy() will only attempt to compact the heap; it | |
1959 // will do nothing further. If we need to bail out for policy reasons, scavenge | |
1960 // before full gc, or any other specialized behavior, it needs to be added here. | |
1961 // | |
1962 // Note that this method should only be called from the vm_thread while at a | |
1963 // safepoint. | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1964 // |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1965 // 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
|
1966 // 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
|
1967 // 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
|
1968 // are being taken to free space. |
0 | 1969 void PSParallelCompact::invoke(bool maximum_heap_compaction) { |
1970 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); | |
1971 assert(Thread::current() == (Thread*)VMThread::vm_thread(), | |
1972 "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
|
1973 |
0 | 1974 ParallelScavengeHeap* heap = gc_heap(); |
1975 GCCause::Cause gc_cause = heap->gc_cause(); | |
1976 assert(!heap->is_gc_active(), "not reentrant"); | |
1977 | |
1978 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
|
1979 IsGCActiveMark mark; |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1980 |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1981 if (ScavengeBeforeFullGC) { |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1982 PSScavenge::invoke_no_policy(); |
0 | 1983 } |
1387
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 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
|
1986 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
|
1987 |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
1988 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
|
1989 maximum_heap_compaction); |
0 | 1990 } |
1991 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1992 bool ParallelCompactData::region_contains(size_t region_index, HeapWord* addr) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1993 size_t addr_region_index = addr_to_region_idx(addr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
1994 return region_index == addr_region_index; |
0 | 1995 } |
1996 | |
1997 // This method contains no policy. You should probably | |
1998 // be calling invoke() instead. | |
1999 void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { | |
2000 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); | |
2001 assert(ref_processor() != NULL, "Sanity"); | |
2002 | |
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
|
2003 if (GC_locker::check_active_before_gc()) { |
0 | 2004 return; |
2005 } | |
2006 | |
2007 TimeStamp marking_start; | |
2008 TimeStamp compaction_start; | |
2009 TimeStamp collection_exit; | |
2010 | |
2011 ParallelScavengeHeap* heap = gc_heap(); | |
2012 GCCause::Cause gc_cause = heap->gc_cause(); | |
2013 PSYoungGen* young_gen = heap->young_gen(); | |
2014 PSOldGen* old_gen = heap->old_gen(); | |
2015 PSPermGen* perm_gen = heap->perm_gen(); | |
2016 PSAdaptiveSizePolicy* size_policy = heap->size_policy(); | |
2017 | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
2018 // 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
|
2019 // 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
|
2020 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
|
2021 heap->collector_policy()); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
2022 |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2023 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2024 // 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
|
2025 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
|
2026 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2027 |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
2028 heap->pre_full_gc_dump(); |
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
2029 |
0 | 2030 _print_phases = PrintGCDetails && PrintParallelOldGCPhaseTimes; |
2031 | |
2032 // Make sure data structures are sane, make the heap parsable, and do other | |
2033 // miscellaneous bookkeeping. | |
2034 PreGCValues pre_gc_values; | |
2035 pre_compact(&pre_gc_values); | |
2036 | |
210 | 2037 // Get the compaction manager reserved for the VM thread. |
2038 ParCompactionManager* const vmthread_cm = | |
2039 ParCompactionManager::manager_array(gc_task_manager()->workers()); | |
2040 | |
0 | 2041 // Place after pre_compact() where the number of invocations is incremented. |
2042 AdaptiveSizePolicyOutput(size_policy, heap->total_collections()); | |
2043 | |
2044 { | |
2045 ResourceMark rm; | |
2046 HandleMark hm; | |
2047 | |
2048 const bool is_system_gc = gc_cause == GCCause::_java_lang_system_gc; | |
2049 | |
2050 // This is useful for debugging but don't change the output the | |
2051 // the customer sees. | |
2052 const char* gc_cause_str = "Full GC"; | |
2053 if (is_system_gc && PrintGCDetails) { | |
2054 gc_cause_str = "Full GC (System)"; | |
2055 } | |
2056 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); | |
2057 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); | |
2058 TraceTime t1(gc_cause_str, PrintGC, !PrintGCDetails, gclog_or_tty); | |
2059 TraceCollectorStats tcs(counters()); | |
3356
78542e2b5e35
7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents:
3251
diff
changeset
|
2060 TraceMemoryManagerStats tms(true /* Full GC */,gc_cause); |
0 | 2061 |
2062 if (TraceGen1Time) accumulated_time()->start(); | |
2063 | |
2064 // Let the size policy know we're starting | |
2065 size_policy->major_collection_begin(); | |
2066 | |
2067 // When collecting the permanent generation methodOops may be moving, | |
2068 // so we either have to flush all bcp data or convert it into bci. | |
2069 CodeCache::gc_prologue(); | |
2070 Threads::gc_prologue(); | |
2071 | |
2072 COMPILER2_PRESENT(DerivedPointerTable::clear()); | |
2073 | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3915
diff
changeset
|
2074 ref_processor()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
2075 ref_processor()->setup_policy(maximum_heap_compaction); |
0 | 2076 |
2077 bool marked_for_unloading = false; | |
2078 | |
2079 marking_start.update(); | |
210 | 2080 marking_phase(vmthread_cm, maximum_heap_compaction); |
0 | 2081 |
2082 #ifndef PRODUCT | |
2083 if (TraceParallelOldGCMarkingPhase) { | |
2084 gclog_or_tty->print_cr("marking_phase: cas_tries %d cas_retries %d " | |
2085 "cas_by_another %d", | |
2086 mark_bitmap()->cas_tries(), mark_bitmap()->cas_retries(), | |
2087 mark_bitmap()->cas_by_another()); | |
2088 } | |
2089 #endif // #ifndef PRODUCT | |
2090 | |
2091 bool max_on_system_gc = UseMaximumCompactionOnSystemGC && is_system_gc; | |
210 | 2092 summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc); |
0 | 2093 |
2094 COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity")); | |
2095 COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); | |
2096 | |
2097 // adjust_roots() updates Universe::_intArrayKlassObj which is | |
2098 // needed by the compaction for filling holes in the dense prefix. | |
2099 adjust_roots(); | |
2100 | |
2101 compaction_start.update(); | |
2102 // Does the perm gen always have to be done serially because | |
2103 // klasses are used in the update of an object? | |
210 | 2104 compact_perm(vmthread_cm); |
0 | 2105 |
3251
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2106 compact(); |
0 | 2107 |
2108 // Reset the mark bitmap, summary data, and do other bookkeeping. Must be | |
2109 // done before resizing. | |
2110 post_compact(); | |
2111 | |
2112 // Let the size policy know we're done | |
2113 size_policy->major_collection_end(old_gen->used_in_bytes(), gc_cause); | |
2114 | |
2115 if (UseAdaptiveSizePolicy) { | |
2116 if (PrintAdaptiveSizePolicy) { | |
2117 gclog_or_tty->print("AdaptiveSizeStart: "); | |
2118 gclog_or_tty->stamp(); | |
2119 gclog_or_tty->print_cr(" collection: %d ", | |
2120 heap->total_collections()); | |
2121 if (Verbose) { | |
2122 gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d" | |
2123 " perm_gen_capacity: %d ", | |
2124 old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes(), | |
2125 perm_gen->capacity_in_bytes()); | |
2126 } | |
2127 } | |
2128 | |
2129 // Don't check if the size_policy is ready here. Let | |
2130 // the size_policy check that internally. | |
2131 if (UseAdaptiveGenerationSizePolicyAtMajorCollection && | |
2132 ((gc_cause != GCCause::_java_lang_system_gc) || | |
2133 UseAdaptiveSizePolicyWithSystemGC)) { | |
2134 // Calculate optimal free space amounts | |
2135 assert(young_gen->max_size() > | |
2136 young_gen->from_space()->capacity_in_bytes() + | |
2137 young_gen->to_space()->capacity_in_bytes(), | |
2138 "Sizes of space in young gen are out-of-bounds"); | |
2139 size_t max_eden_size = young_gen->max_size() - | |
2140 young_gen->from_space()->capacity_in_bytes() - | |
2141 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
|
2142 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
|
2143 young_gen->used_in_bytes(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2144 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
|
2145 old_gen->used_in_bytes(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2146 perm_gen->used_in_bytes(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2147 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
|
2148 old_gen->max_gen_size(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2149 max_eden_size, |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2150 true /* full gc*/, |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
2151 gc_cause, |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
2152 heap->collector_policy()); |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2153 |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2154 heap->resize_old_gen( |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2155 size_policy->calculated_old_free_size_in_bytes()); |
0 | 2156 |
2157 // Don't resize the young generation at an major collection. A | |
2158 // desired young generation size may have been calculated but | |
2159 // resizing the young generation complicates the code because the | |
2160 // resizing of the old generation may have moved the boundary | |
2161 // between the young generation and the old generation. Let the | |
2162 // young generation resizing happen at the minor collections. | |
2163 } | |
2164 if (PrintAdaptiveSizePolicy) { | |
2165 gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ", | |
2166 heap->total_collections()); | |
2167 } | |
2168 } | |
2169 | |
2170 if (UsePerfData) { | |
2171 PSGCAdaptivePolicyCounters* const counters = heap->gc_policy_counters(); | |
2172 counters->update_counters(); | |
2173 counters->update_old_capacity(old_gen->capacity_in_bytes()); | |
2174 counters->update_young_capacity(young_gen->capacity_in_bytes()); | |
2175 } | |
2176 | |
2177 heap->resize_all_tlabs(); | |
2178 | |
2179 // We collected the perm gen, so we'll resize it here. | |
2180 perm_gen->compute_new_size(pre_gc_values.perm_gen_used()); | |
2181 | |
2182 if (TraceGen1Time) accumulated_time()->stop(); | |
2183 | |
2184 if (PrintGC) { | |
2185 if (PrintGCDetails) { | |
2186 // No GC timestamp here. This is after GC so it would be confusing. | |
2187 young_gen->print_used_change(pre_gc_values.young_gen_used()); | |
2188 old_gen->print_used_change(pre_gc_values.old_gen_used()); | |
2189 heap->print_heap_change(pre_gc_values.heap_used()); | |
2190 // Print perm gen last (print_heap_change() excludes the perm gen). | |
2191 perm_gen->print_used_change(pre_gc_values.perm_gen_used()); | |
2192 } else { | |
2193 heap->print_heap_change(pre_gc_values.heap_used()); | |
2194 } | |
2195 } | |
2196 | |
2197 // Track memory usage and detect low memory | |
2198 MemoryService::track_memory_usage(); | |
2199 heap->update_counters(); | |
2200 } | |
2201 | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2202 #ifdef ASSERT |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2203 for (size_t i = 0; i < ParallelGCThreads + 1; ++i) { |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2204 ParCompactionManager* const cm = |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2205 ParCompactionManager::manager_array(int(i)); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2206 assert(cm->marking_stack()->is_empty(), "should be empty"); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2207 assert(cm->region_stack()->is_empty(), "should be empty"); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2208 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
|
2209 } |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2210 #endif // ASSERT |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2211 |
0 | 2212 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) { |
2213 HandleMark hm; // Discard invalid handles created during verification | |
2214 gclog_or_tty->print(" VerifyAfterGC:"); | |
2215 Universe::verify(false); | |
2216 } | |
2217 | |
2218 // Re-verify object start arrays | |
2219 if (VerifyObjectStartArray && | |
2220 VerifyAfterGC) { | |
2221 old_gen->verify_object_start_array(); | |
2222 perm_gen->verify_object_start_array(); | |
2223 } | |
2224 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2225 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2226 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
|
2227 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
|
2228 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2229 |
0 | 2230 NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); |
2231 | |
2232 collection_exit.update(); | |
2233 | |
2234 if (PrintHeapAtGC) { | |
2235 Universe::print_heap_after_gc(); | |
2236 } | |
2237 if (PrintGCTaskTimeStamps) { | |
2238 gclog_or_tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " " | |
2239 INT64_FORMAT, | |
2240 marking_start.ticks(), compaction_start.ticks(), | |
2241 collection_exit.ticks()); | |
2242 gc_task_manager()->print_task_time_stamps(); | |
2243 } | |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
496
diff
changeset
|
2244 |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
2245 heap->post_full_gc_dump(); |
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
2246 |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
496
diff
changeset
|
2247 #ifdef TRACESPINNING |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
496
diff
changeset
|
2248 ParallelTaskTerminator::print_termination_counts(); |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
496
diff
changeset
|
2249 #endif |
0 | 2250 } |
2251 | |
2252 bool PSParallelCompact::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy, | |
2253 PSYoungGen* young_gen, | |
2254 PSOldGen* old_gen) { | |
2255 MutableSpace* const eden_space = young_gen->eden_space(); | |
2256 assert(!eden_space->is_empty(), "eden must be non-empty"); | |
2257 assert(young_gen->virtual_space()->alignment() == | |
2258 old_gen->virtual_space()->alignment(), "alignments do not match"); | |
2259 | |
2260 if (!(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary)) { | |
2261 return false; | |
2262 } | |
2263 | |
2264 // Both generations must be completely committed. | |
2265 if (young_gen->virtual_space()->uncommitted_size() != 0) { | |
2266 return false; | |
2267 } | |
2268 if (old_gen->virtual_space()->uncommitted_size() != 0) { | |
2269 return false; | |
2270 } | |
2271 | |
2272 // Figure out how much to take from eden. Include the average amount promoted | |
2273 // in the total; otherwise the next young gen GC will simply bail out to a | |
2274 // full GC. | |
2275 const size_t alignment = old_gen->virtual_space()->alignment(); | |
2276 const size_t eden_used = eden_space->used_in_bytes(); | |
2277 const size_t promoted = (size_t)size_policy->avg_promoted()->padded_average(); | |
2278 const size_t absorb_size = align_size_up(eden_used + promoted, alignment); | |
2279 const size_t eden_capacity = eden_space->capacity_in_bytes(); | |
2280 | |
2281 if (absorb_size >= eden_capacity) { | |
2282 return false; // Must leave some space in eden. | |
2283 } | |
2284 | |
2285 const size_t new_young_size = young_gen->capacity_in_bytes() - absorb_size; | |
2286 if (new_young_size < young_gen->min_gen_size()) { | |
2287 return false; // Respect young gen minimum size. | |
2288 } | |
2289 | |
2290 if (TraceAdaptiveGCBoundary && Verbose) { | |
2291 gclog_or_tty->print(" absorbing " SIZE_FORMAT "K: " | |
2292 "eden " SIZE_FORMAT "K->" SIZE_FORMAT "K " | |
2293 "from " SIZE_FORMAT "K, to " SIZE_FORMAT "K " | |
2294 "young_gen " SIZE_FORMAT "K->" SIZE_FORMAT "K ", | |
2295 absorb_size / K, | |
2296 eden_capacity / K, (eden_capacity - absorb_size) / K, | |
2297 young_gen->from_space()->used_in_bytes() / K, | |
2298 young_gen->to_space()->used_in_bytes() / K, | |
2299 young_gen->capacity_in_bytes() / K, new_young_size / K); | |
2300 } | |
2301 | |
2302 // Fill the unused part of the old gen. | |
2303 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
|
2304 HeapWord* const unused_start = old_space->top(); |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2305 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
|
2306 |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2307 if (unused_words > 0) { |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2308 if (unused_words < CollectedHeap::min_fill_size()) { |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2309 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
|
2310 } |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2311 CollectedHeap::fill_with_objects(unused_start, unused_words); |
0 | 2312 } |
2313 | |
2314 // Take the live data from eden and set both top and end in the old gen to | |
2315 // eden top. (Need to set end because reset_after_change() mangles the region | |
2316 // from end to virtual_space->high() in debug builds). | |
2317 HeapWord* const new_top = eden_space->top(); | |
2318 old_gen->virtual_space()->expand_into(young_gen->virtual_space(), | |
2319 absorb_size); | |
2320 young_gen->reset_after_change(); | |
2321 old_space->set_top(new_top); | |
2322 old_space->set_end(new_top); | |
2323 old_gen->reset_after_change(); | |
2324 | |
2325 // Update the object start array for the filler object and the data from eden. | |
2326 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
|
2327 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
|
2328 start_array->allocate_block(p); |
0 | 2329 } |
2330 | |
2331 // Could update the promoted average here, but it is not typically updated at | |
2332 // full GCs and the value to use is unclear. Something like | |
2333 // | |
2334 // cur_promoted_avg + absorb_size / number_of_scavenges_since_last_full_gc. | |
2335 | |
2336 size_policy->set_bytes_absorbed_from_eden(absorb_size); | |
2337 return true; | |
2338 } | |
2339 | |
2340 GCTaskManager* const PSParallelCompact::gc_task_manager() { | |
2341 assert(ParallelScavengeHeap::gc_task_manager() != NULL, | |
2342 "shouldn't return NULL"); | |
2343 return ParallelScavengeHeap::gc_task_manager(); | |
2344 } | |
2345 | |
2346 void PSParallelCompact::marking_phase(ParCompactionManager* cm, | |
2347 bool maximum_heap_compaction) { | |
2348 // Recursively traverse all live objects and mark them | |
2349 EventMark m("1 mark object"); | |
2350 TraceTime tm("marking phase", print_phases(), true, gclog_or_tty); | |
2351 | |
2352 ParallelScavengeHeap* heap = gc_heap(); | |
2353 uint parallel_gc_threads = heap->gc_task_manager()->workers(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2354 TaskQueueSetSuper* qset = ParCompactionManager::region_array(); |
0 | 2355 ParallelTaskTerminator terminator(parallel_gc_threads, qset); |
2356 | |
2357 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); | |
2358 PSParallelCompact::FollowStackClosure follow_stack_closure(cm); | |
2359 | |
2360 { | |
2361 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
|
2362 ParallelScavengeHeap::ParStrongRootsScope psrs; |
0 | 2363 |
2364 GCTaskQueue* q = GCTaskQueue::create(); | |
2365 | |
2366 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::universe)); | |
2367 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jni_handles)); | |
2368 // We scan the thread roots in parallel | |
2369 Threads::create_thread_roots_marking_tasks(q); | |
2370 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::object_synchronizer)); | |
2371 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::flat_profiler)); | |
2372 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management)); | |
2373 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary)); | |
2374 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti)); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
696
diff
changeset
|
2375 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache)); |
0 | 2376 |
2377 if (parallel_gc_threads > 1) { | |
2378 for (uint j = 0; j < parallel_gc_threads; j++) { | |
2379 q->enqueue(new StealMarkingTask(&terminator)); | |
2380 } | |
2381 } | |
2382 | |
2383 WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create(); | |
2384 q->enqueue(fin); | |
2385 | |
2386 gc_task_manager()->add_list(q); | |
2387 | |
2388 fin->wait_for(); | |
2389 | |
2390 // We have to release the barrier tasks! | |
2391 WaitForBarrierGCTask::destroy(fin); | |
2392 } | |
2393 | |
2394 // Process reference objects found during marking | |
2395 { | |
2396 TraceTime tm_r("reference processing", print_phases(), true, gclog_or_tty); | |
2397 if (ref_processor()->processing_is_mt()) { | |
2398 RefProcTaskExecutor task_executor; | |
2399 ref_processor()->process_discovered_references( | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
376
diff
changeset
|
2400 is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
376
diff
changeset
|
2401 &task_executor); |
0 | 2402 } else { |
2403 ref_processor()->process_discovered_references( | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
376
diff
changeset
|
2404 is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL); |
0 | 2405 } |
2406 } | |
2407 | |
2408 TraceTime tm_c("class unloading", print_phases(), true, gclog_or_tty); | |
2409 // Follow system dictionary roots and unload classes. | |
2410 bool purged_class = SystemDictionary::do_unloading(is_alive_closure()); | |
2411 | |
2412 // Follow code cache roots. | |
2413 CodeCache::do_unloading(is_alive_closure(), &mark_and_push_closure, | |
2414 purged_class); | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
997
diff
changeset
|
2415 cm->follow_marking_stacks(); // Flush marking stack. |
0 | 2416 |
2417 // Update subklass/sibling/implementor links of live klasses | |
2418 // revisit_klass_stack is used in follow_weak_klass_links(). | |
941 | 2419 follow_weak_klass_links(); |
2420 | |
2421 // Revisit memoized MDO's and clear any unmarked weak refs | |
2422 follow_mdo_weak_refs(); | |
0 | 2423 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
2424 // Visit interned string tables and delete unmarked oops |
0 | 2425 StringTable::unlink(is_alive_closure()); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
2426 // Clean up unreferenced symbols in symbol table. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
2427 SymbolTable::unlink(); |
0 | 2428 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
997
diff
changeset
|
2429 assert(cm->marking_stacks_empty(), "marking stacks should be empty"); |
0 | 2430 } |
2431 | |
2432 // This should be moved to the shared markSweep code! | |
2433 class PSAlwaysTrueClosure: public BoolObjectClosure { | |
2434 public: | |
2435 void do_object(oop p) { ShouldNotReachHere(); } | |
2436 bool do_object_b(oop p) { return true; } | |
2437 }; | |
2438 static PSAlwaysTrueClosure always_true; | |
2439 | |
2440 void PSParallelCompact::adjust_roots() { | |
2441 // Adjust the pointers to reflect the new locations | |
2442 EventMark m("3 adjust roots"); | |
2443 TraceTime tm("adjust roots", print_phases(), true, gclog_or_tty); | |
2444 | |
2445 // General strong roots. | |
2446 Universe::oops_do(adjust_root_pointer_closure()); | |
2447 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
|
2448 Threads::oops_do(adjust_root_pointer_closure(), NULL); |
0 | 2449 ObjectSynchronizer::oops_do(adjust_root_pointer_closure()); |
2450 FlatProfiler::oops_do(adjust_root_pointer_closure()); | |
2451 Management::oops_do(adjust_root_pointer_closure()); | |
2452 JvmtiExport::oops_do(adjust_root_pointer_closure()); | |
2453 // SO_AllClasses | |
2454 SystemDictionary::oops_do(adjust_root_pointer_closure()); | |
2455 | |
2456 // Now adjust pointers in remaining weak roots. (All of which should | |
2457 // have been cleared if they pointed to non-surviving objects.) | |
2458 // Global (weak) JNI handles | |
2459 JNIHandles::weak_oops_do(&always_true, adjust_root_pointer_closure()); | |
2460 | |
2461 CodeCache::oops_do(adjust_pointer_closure()); | |
2462 StringTable::oops_do(adjust_root_pointer_closure()); | |
2463 ref_processor()->weak_oops_do(adjust_root_pointer_closure()); | |
2464 // Roots were visited so references into the young gen in roots | |
2465 // may have been scanned. Process them also. | |
2466 // Should the reference processor have a span that excludes | |
2467 // young gen objects? | |
2468 PSScavenge::reference_processor()->weak_oops_do( | |
2469 adjust_root_pointer_closure()); | |
2470 } | |
2471 | |
2472 void PSParallelCompact::compact_perm(ParCompactionManager* cm) { | |
2473 EventMark m("4 compact perm"); | |
2474 TraceTime tm("compact perm gen", print_phases(), true, gclog_or_tty); | |
2475 // trace("4"); | |
2476 | |
2477 gc_heap()->perm_gen()->start_array()->reset(); | |
2478 move_and_update(cm, perm_space_id); | |
2479 } | |
2480 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2481 void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2482 uint parallel_gc_threads) |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2483 { |
0 | 2484 TraceTime tm("drain task setup", print_phases(), true, gclog_or_tty); |
2485 | |
2486 const unsigned int task_count = MAX2(parallel_gc_threads, 1U); | |
2487 for (unsigned int j = 0; j < task_count; j++) { | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1638
diff
changeset
|
2488 q->enqueue(new DrainStacksCompactionTask(j)); |
0 | 2489 } |
2490 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2491 // Find all regions that are available (can be filled immediately) and |
0 | 2492 // 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
|
2493 // order (high to low) so the regions will be removed in ascending order. |
0 | 2494 |
2495 const ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
2496 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2497 size_t fillable_regions = 0; // A count for diagnostic purposes. |
0 | 2498 unsigned int which = 0; // The worker thread number. |
2499 | |
2500 for (unsigned int id = to_space_id; id > perm_space_id; --id) { | |
2501 SpaceInfo* const space_info = _space_info + id; | |
2502 MutableSpace* const space = space_info->space(); | |
2503 HeapWord* const new_top = space_info->new_top(); | |
2504 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2505 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
|
2506 const size_t end_region = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2507 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
|
2508 assert(end_region > 0, "perm gen cannot be empty"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2509 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2510 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
|
2511 if (sd.region(cur)->claim_unsafe()) { |
0 | 2512 ParCompactionManager* cm = ParCompactionManager::manager_array(which); |
1638 | 2513 cm->push_region(cur); |
0 | 2514 |
2515 if (TraceParallelOldGCCompactionPhase && Verbose) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2516 const size_t count_mod_8 = fillable_regions & 7; |
0 | 2517 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
|
2518 gclog_or_tty->print(" " SIZE_FORMAT_W(7), cur); |
0 | 2519 if (count_mod_8 == 7) gclog_or_tty->cr(); |
2520 } | |
2521 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2522 NOT_PRODUCT(++fillable_regions;) |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2523 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2524 // Assign regions to threads in round-robin fashion. |
0 | 2525 if (++which == task_count) { |
2526 which = 0; | |
2527 } | |
2528 } | |
2529 } | |
2530 } | |
2531 | |
2532 if (TraceParallelOldGCCompactionPhase) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2533 if (Verbose && (fillable_regions & 7) != 0) gclog_or_tty->cr(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2534 gclog_or_tty->print_cr("%u initially fillable regions", fillable_regions); |
0 | 2535 } |
2536 } | |
2537 | |
2538 #define PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING 4 | |
2539 | |
2540 void PSParallelCompact::enqueue_dense_prefix_tasks(GCTaskQueue* q, | |
2541 uint parallel_gc_threads) { | |
2542 TraceTime tm("dense prefix task setup", print_phases(), true, gclog_or_tty); | |
2543 | |
2544 ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
2545 | |
2546 // Iterate over all the spaces adding tasks for updating | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2547 // regions in the dense prefix. Assume that 1 gc thread |
0 | 2548 // will work on opening the gaps and the remaining gc threads |
2549 // will work on the dense prefix. | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2550 unsigned int space_id; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2551 for (space_id = old_space_id; space_id < last_space_id; ++ space_id) { |
0 | 2552 HeapWord* const dense_prefix_end = _space_info[space_id].dense_prefix(); |
2553 const MutableSpace* const space = _space_info[space_id].space(); | |
2554 | |
2555 if (dense_prefix_end == space->bottom()) { | |
2556 // There is no dense prefix for this space. | |
2557 continue; | |
2558 } | |
2559 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2560 // The dense prefix is before this region. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2561 size_t region_index_end_dense_prefix = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2562 sd.addr_to_region_idx(dense_prefix_end); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2563 RegionData* const dense_prefix_cp = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2564 sd.region(region_index_end_dense_prefix); |
0 | 2565 assert(dense_prefix_end == space->end() || |
2566 dense_prefix_cp->available() || | |
2567 dense_prefix_cp->claimed(), | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2568 "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
|
2569 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2570 size_t region_index_start = sd.addr_to_region_idx(space->bottom()); |
0 | 2571 |
2572 // Is there dense prefix work? | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2573 size_t total_dense_prefix_regions = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2574 region_index_end_dense_prefix - region_index_start; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2575 // How many regions of the dense prefix should be given to |
0 | 2576 // each thread? |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2577 if (total_dense_prefix_regions > 0) { |
0 | 2578 uint tasks_for_dense_prefix = 1; |
3251
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2579 if (total_dense_prefix_regions <= |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2580 (parallel_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING)) { |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2581 // Don't over partition. This assumes that |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2582 // PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING is a small integer value |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2583 // so there are not many regions to process. |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2584 tasks_for_dense_prefix = parallel_gc_threads; |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2585 } else { |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2586 // Over partition |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2587 tasks_for_dense_prefix = parallel_gc_threads * |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2588 PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING; |
0 | 2589 } |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2590 size_t regions_per_thread = total_dense_prefix_regions / |
0 | 2591 tasks_for_dense_prefix; |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2592 // Give each thread at least 1 region. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2593 if (regions_per_thread == 0) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2594 regions_per_thread = 1; |
0 | 2595 } |
2596 | |
2597 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
|
2598 if (region_index_start >= region_index_end_dense_prefix) { |
0 | 2599 break; |
2600 } | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2601 // region_index_end is not processed |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2602 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
|
2603 region_index_end_dense_prefix); |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2604 q->enqueue(new UpdateDensePrefixTask(SpaceId(space_id), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2605 region_index_start, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2606 region_index_end)); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2607 region_index_start = region_index_end; |
0 | 2608 } |
2609 } | |
2610 // This gets any part of the dense prefix that did not | |
2611 // fit evenly. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2612 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
|
2613 q->enqueue(new UpdateDensePrefixTask(SpaceId(space_id), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2614 region_index_start, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2615 region_index_end_dense_prefix)); |
0 | 2616 } |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2617 } |
0 | 2618 } |
2619 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2620 void PSParallelCompact::enqueue_region_stealing_tasks( |
0 | 2621 GCTaskQueue* q, |
2622 ParallelTaskTerminator* terminator_ptr, | |
2623 uint parallel_gc_threads) { | |
2624 TraceTime tm("steal task setup", print_phases(), true, gclog_or_tty); | |
2625 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2626 // Once a thread has drained it's stack, it should try to steal regions from |
0 | 2627 // other threads. |
2628 if (parallel_gc_threads > 1) { | |
2629 for (uint j = 0; j < parallel_gc_threads; j++) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2630 q->enqueue(new StealRegionCompactionTask(terminator_ptr)); |
0 | 2631 } |
2632 } | |
2633 } | |
2634 | |
2635 void PSParallelCompact::compact() { | |
2636 EventMark m("5 compact"); | |
2637 // trace("5"); | |
2638 TraceTime tm("compaction phase", print_phases(), true, gclog_or_tty); | |
2639 | |
2640 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
2641 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
2642 PSOldGen* old_gen = heap->old_gen(); | |
2643 old_gen->start_array()->reset(); | |
2644 uint parallel_gc_threads = heap->gc_task_manager()->workers(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2645 TaskQueueSetSuper* qset = ParCompactionManager::region_array(); |
0 | 2646 ParallelTaskTerminator terminator(parallel_gc_threads, qset); |
2647 | |
2648 GCTaskQueue* q = GCTaskQueue::create(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2649 enqueue_region_draining_tasks(q, parallel_gc_threads); |
0 | 2650 enqueue_dense_prefix_tasks(q, parallel_gc_threads); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2651 enqueue_region_stealing_tasks(q, &terminator, parallel_gc_threads); |
0 | 2652 |
2653 { | |
2654 TraceTime tm_pc("par compact", print_phases(), true, gclog_or_tty); | |
2655 | |
2656 WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create(); | |
2657 q->enqueue(fin); | |
2658 | |
2659 gc_task_manager()->add_list(q); | |
2660 | |
2661 fin->wait_for(); | |
2662 | |
2663 // We have to release the barrier tasks! | |
2664 WaitForBarrierGCTask::destroy(fin); | |
2665 | |
2666 #ifdef ASSERT | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2667 // Verify that all regions have been processed before the deferred updates. |
0 | 2668 // 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
|
2669 // valid until the perm gen is compacted by regions. |
0 | 2670 for (unsigned int id = old_space_id; id < last_space_id; ++id) { |
2671 verify_complete(SpaceId(id)); | |
2672 } | |
2673 #endif | |
2674 } | |
2675 | |
2676 { | |
2677 // Update the deferred objects, if any. Any compaction manager can be used. | |
2678 TraceTime tm_du("deferred updates", print_phases(), true, gclog_or_tty); | |
2679 ParCompactionManager* cm = ParCompactionManager::manager_array(0); | |
2680 for (unsigned int id = old_space_id; id < last_space_id; ++id) { | |
2681 update_deferred_objects(cm, SpaceId(id)); | |
2682 } | |
2683 } | |
2684 } | |
2685 | |
2686 #ifdef ASSERT | |
2687 void PSParallelCompact::verify_complete(SpaceId space_id) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2688 // 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
|
2689 // and all Regions between new_top() and top() should be available (i.e., |
0 | 2690 // should have been emptied). |
2691 ParallelCompactData& sd = summary_data(); | |
2692 SpaceInfo si = _space_info[space_id]; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2693 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
|
2694 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
|
2695 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
|
2696 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
|
2697 const size_t old_top_region = sd.addr_to_region_idx(old_top_addr); |
0 | 2698 |
2699 bool issued_a_warning = false; | |
2700 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2701 size_t cur_region; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2702 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
|
2703 const RegionData* const c = sd.region(cur_region); |
0 | 2704 if (!c->completed()) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2705 warning("region " SIZE_FORMAT " not filled: " |
0 | 2706 "destination_count=" SIZE_FORMAT, |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2707 cur_region, c->destination_count()); |
0 | 2708 issued_a_warning = true; |
2709 } | |
2710 } | |
2711 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2712 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
|
2713 const RegionData* const c = sd.region(cur_region); |
0 | 2714 if (!c->available()) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2715 warning("region " SIZE_FORMAT " not empty: " |
0 | 2716 "destination_count=" SIZE_FORMAT, |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2717 cur_region, c->destination_count()); |
0 | 2718 issued_a_warning = true; |
2719 } | |
2720 } | |
2721 | |
2722 if (issued_a_warning) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2723 print_region_ranges(); |
0 | 2724 } |
2725 } | |
2726 #endif // #ifdef ASSERT | |
2727 | |
2728 void | |
941 | 2729 PSParallelCompact::follow_weak_klass_links() { |
0 | 2730 // All klasses on the revisit stack are marked at this point. |
2731 // Update and follow all subklass, sibling and implementor links. | |
941 | 2732 if (PrintRevisitStats) { |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2733 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
|
2734 SystemDictionary::number_of_classes()); |
941 | 2735 } |
2736 for (uint i = 0; i < ParallelGCThreads + 1; i++) { | |
0 | 2737 ParCompactionManager* cm = ParCompactionManager::manager_array(i); |
2738 KeepAliveClosure keep_alive_closure(cm); | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2739 Stack<Klass*>* const rks = cm->revisit_klass_stack(); |
941 | 2740 if (PrintRevisitStats) { |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2741 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
|
2742 i, rks->size()); |
941 | 2743 } |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2744 while (!rks->is_empty()) { |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2745 Klass* const k = rks->pop(); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2746 k->follow_weak_klass_links(is_alive_closure(), &keep_alive_closure); |
0 | 2747 } |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2748 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
997
diff
changeset
|
2749 cm->follow_marking_stacks(); |
0 | 2750 } |
2751 } | |
2752 | |
2753 void | |
2754 PSParallelCompact::revisit_weak_klass_link(ParCompactionManager* cm, Klass* k) { | |
2755 cm->revisit_klass_stack()->push(k); | |
2756 } | |
2757 | |
941 | 2758 void PSParallelCompact::revisit_mdo(ParCompactionManager* cm, DataLayout* p) { |
2759 cm->revisit_mdo_stack()->push(p); | |
2760 } | |
2761 | |
2762 void PSParallelCompact::follow_mdo_weak_refs() { | |
2763 // All strongly reachable oops have been marked at this point; | |
2764 // we can visit and clear any weak references from MDO's which | |
2765 // we memoized during the strong marking phase. | |
2766 if (PrintRevisitStats) { | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2767 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
|
2768 SystemDictionary::number_of_classes()); |
941 | 2769 } |
2770 for (uint i = 0; i < ParallelGCThreads + 1; i++) { | |
2771 ParCompactionManager* cm = ParCompactionManager::manager_array(i); | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2772 Stack<DataLayout*>* rms = cm->revisit_mdo_stack(); |
941 | 2773 if (PrintRevisitStats) { |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2774 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
|
2775 i, rms->size()); |
941 | 2776 } |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2777 while (!rms->is_empty()) { |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2778 rms->pop()->follow_weak_refs(is_alive_closure()); |
941 | 2779 } |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2780 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
997
diff
changeset
|
2781 cm->follow_marking_stacks(); |
941 | 2782 } |
2783 } | |
2784 | |
2785 | |
0 | 2786 #ifdef VALIDATE_MARK_SWEEP |
2787 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
2788 void PSParallelCompact::track_adjusted_pointer(void* p, bool isroot) { |
0 | 2789 if (!ValidateMarkSweep) |
2790 return; | |
2791 | |
2792 if (!isroot) { | |
2793 if (_pointer_tracking) { | |
2794 guarantee(_adjusted_pointers->contains(p), "should have seen this pointer"); | |
2795 _adjusted_pointers->remove(p); | |
2796 } | |
2797 } else { | |
2798 ptrdiff_t index = _root_refs_stack->find(p); | |
2799 if (index != -1) { | |
2800 int l = _root_refs_stack->length(); | |
2801 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
|
2802 void* last = _root_refs_stack->pop(); |
0 | 2803 assert(last != p, "should be different"); |
2804 _root_refs_stack->at_put(index, last); | |
2805 } else { | |
2806 _root_refs_stack->remove(p); | |
2807 } | |
2808 } | |
2809 } | |
2810 } | |
2811 | |
2812 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
2813 void PSParallelCompact::check_adjust_pointer(void* p) { |
0 | 2814 _adjusted_pointers->push(p); |
2815 } | |
2816 | |
2817 | |
2818 class AdjusterTracker: public OopClosure { | |
2819 public: | |
2820 AdjusterTracker() {}; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
2821 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
|
2822 void do_oop(narrowOop* o) { PSParallelCompact::check_adjust_pointer(o); } |
0 | 2823 }; |
2824 | |
2825 | |
2826 void PSParallelCompact::track_interior_pointers(oop obj) { | |
2827 if (ValidateMarkSweep) { | |
2828 _adjusted_pointers->clear(); | |
2829 _pointer_tracking = true; | |
2830 | |
2831 AdjusterTracker checker; | |
2832 obj->oop_iterate(&checker); | |
2833 } | |
2834 } | |
2835 | |
2836 | |
2837 void PSParallelCompact::check_interior_pointers() { | |
2838 if (ValidateMarkSweep) { | |
2839 _pointer_tracking = false; | |
2840 guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers"); | |
2841 } | |
2842 } | |
2843 | |
2844 | |
2845 void PSParallelCompact::reset_live_oop_tracking(bool at_perm) { | |
2846 if (ValidateMarkSweep) { | |
2847 guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops"); | |
2848 _live_oops_index = at_perm ? _live_oops_index_at_perm : 0; | |
2849 } | |
2850 } | |
2851 | |
2852 | |
2853 void PSParallelCompact::register_live_oop(oop p, size_t size) { | |
2854 if (ValidateMarkSweep) { | |
2855 _live_oops->push(p); | |
2856 _live_oops_size->push(size); | |
2857 _live_oops_index++; | |
2858 } | |
2859 } | |
2860 | |
2861 void PSParallelCompact::validate_live_oop(oop p, size_t size) { | |
2862 if (ValidateMarkSweep) { | |
2863 oop obj = _live_oops->at((int)_live_oops_index); | |
2864 guarantee(obj == p, "should be the same object"); | |
2865 guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size"); | |
2866 _live_oops_index++; | |
2867 } | |
2868 } | |
2869 | |
2870 void PSParallelCompact::live_oop_moved_to(HeapWord* q, size_t size, | |
2871 HeapWord* compaction_top) { | |
2872 assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top), | |
2873 "should be moved to forwarded location"); | |
2874 if (ValidateMarkSweep) { | |
2875 PSParallelCompact::validate_live_oop(oop(q), size); | |
2876 _live_oops_moved_to->push(oop(compaction_top)); | |
2877 } | |
2878 if (RecordMarkSweepCompaction) { | |
2879 _cur_gc_live_oops->push(q); | |
2880 _cur_gc_live_oops_moved_to->push(compaction_top); | |
2881 _cur_gc_live_oops_size->push(size); | |
2882 } | |
2883 } | |
2884 | |
2885 | |
2886 void PSParallelCompact::compaction_complete() { | |
2887 if (RecordMarkSweepCompaction) { | |
2888 GrowableArray<HeapWord*>* _tmp_live_oops = _cur_gc_live_oops; | |
2889 GrowableArray<HeapWord*>* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to; | |
2890 GrowableArray<size_t> * _tmp_live_oops_size = _cur_gc_live_oops_size; | |
2891 | |
2892 _cur_gc_live_oops = _last_gc_live_oops; | |
2893 _cur_gc_live_oops_moved_to = _last_gc_live_oops_moved_to; | |
2894 _cur_gc_live_oops_size = _last_gc_live_oops_size; | |
2895 _last_gc_live_oops = _tmp_live_oops; | |
2896 _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to; | |
2897 _last_gc_live_oops_size = _tmp_live_oops_size; | |
2898 } | |
2899 } | |
2900 | |
2901 | |
2902 void PSParallelCompact::print_new_location_of_heap_address(HeapWord* q) { | |
2903 if (!RecordMarkSweepCompaction) { | |
2904 tty->print_cr("Requires RecordMarkSweepCompaction to be enabled"); | |
2905 return; | |
2906 } | |
2907 | |
2908 if (_last_gc_live_oops == NULL) { | |
2909 tty->print_cr("No compaction information gathered yet"); | |
2910 return; | |
2911 } | |
2912 | |
2913 for (int i = 0; i < _last_gc_live_oops->length(); i++) { | |
2914 HeapWord* old_oop = _last_gc_live_oops->at(i); | |
2915 size_t sz = _last_gc_live_oops_size->at(i); | |
2916 if (old_oop <= q && q < (old_oop + sz)) { | |
2917 HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i); | |
2918 size_t offset = (q - old_oop); | |
2919 tty->print_cr("Address " PTR_FORMAT, q); | |
2920 tty->print_cr(" Was in oop " PTR_FORMAT ", size %d, at offset %d", old_oop, sz, offset); | |
2921 tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset); | |
2922 return; | |
2923 } | |
2924 } | |
2925 | |
2926 tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q); | |
2927 } | |
2928 #endif //VALIDATE_MARK_SWEEP | |
2929 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2930 // Update interior oops in the ranges of regions [beg_region, end_region). |
0 | 2931 void |
2932 PSParallelCompact::update_and_deadwood_in_dense_prefix(ParCompactionManager* cm, | |
2933 SpaceId space_id, | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2934 size_t beg_region, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2935 size_t end_region) { |
0 | 2936 ParallelCompactData& sd = summary_data(); |
2937 ParMarkBitMap* const mbm = mark_bitmap(); | |
2938 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2939 HeapWord* beg_addr = sd.region_to_addr(beg_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2940 HeapWord* const end_addr = sd.region_to_addr(end_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2941 assert(beg_region <= end_region, "bad region range"); |
0 | 2942 assert(end_addr <= dense_prefix(space_id), "not in the dense prefix"); |
2943 | |
2944 #ifdef ASSERT | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2945 // Claim the regions to avoid triggering an assert when they are marked as |
0 | 2946 // filled. |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2947 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
|
2948 assert(sd.region(claim_region)->claim_unsafe(), "claim() failed"); |
0 | 2949 } |
2950 #endif // #ifdef ASSERT | |
2951 | |
2952 if (beg_addr != space(space_id)->bottom()) { | |
2953 // 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
|
2954 // 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
|
2955 // 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
|
2956 // 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
|
2957 // 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
|
2958 // 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
|
2959 // space. |
0 | 2960 assert(beg_addr > space(space_id)->bottom(), "sanity"); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2961 const RegionData* const cp = sd.region(beg_region); |
0 | 2962 if (cp->partial_obj_size() != 0) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2963 beg_addr = sd.partial_obj_end(beg_region); |
0 | 2964 } else if (dead_space_crosses_boundary(cp, mbm->addr_to_bit(beg_addr))) { |
2965 beg_addr = mbm->find_obj_beg(beg_addr, end_addr); | |
2966 } | |
2967 } | |
2968 | |
2969 if (beg_addr < end_addr) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2970 // A live object or block of dead space starts in this range of Regions. |
0 | 2971 HeapWord* const dense_prefix_end = dense_prefix(space_id); |
2972 | |
2973 // Create closures and iterate. | |
2974 UpdateOnlyClosure update_closure(mbm, cm, space_id); | |
2975 FillClosure fill_closure(cm, space_id); | |
2976 ParMarkBitMap::IterationStatus status; | |
2977 status = mbm->iterate(&update_closure, &fill_closure, beg_addr, end_addr, | |
2978 dense_prefix_end); | |
2979 if (status == ParMarkBitMap::incomplete) { | |
2980 update_closure.do_addr(update_closure.source()); | |
2981 } | |
2982 } | |
2983 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2984 // Mark the regions as filled. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2985 RegionData* const beg_cp = sd.region(beg_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2986 RegionData* const end_cp = sd.region(end_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2987 for (RegionData* cp = beg_cp; cp < end_cp; ++cp) { |
0 | 2988 cp->set_completed(); |
2989 } | |
2990 } | |
2991 | |
2992 // Return the SpaceId for the space containing addr. If addr is not in the | |
2993 // heap, last_space_id is returned. In debug mode it expects the address to be | |
2994 // in the heap and asserts such. | |
2995 PSParallelCompact::SpaceId PSParallelCompact::space_id(HeapWord* addr) { | |
2996 assert(Universe::heap()->is_in_reserved(addr), "addr not in the heap"); | |
2997 | |
2998 for (unsigned int id = perm_space_id; id < last_space_id; ++id) { | |
2999 if (_space_info[id].space()->contains(addr)) { | |
3000 return SpaceId(id); | |
3001 } | |
3002 } | |
3003 | |
3004 assert(false, "no space contains the addr"); | |
3005 return last_space_id; | |
3006 } | |
3007 | |
3008 void PSParallelCompact::update_deferred_objects(ParCompactionManager* cm, | |
3009 SpaceId id) { | |
3010 assert(id < last_space_id, "bad space id"); | |
3011 | |
3012 ParallelCompactData& sd = summary_data(); | |
3013 const SpaceInfo* const space_info = _space_info + id; | |
3014 ObjectStartArray* const start_array = space_info->start_array(); | |
3015 | |
3016 const MutableSpace* const space = space_info->space(); | |
3017 assert(space_info->dense_prefix() >= space->bottom(), "dense_prefix not set"); | |
3018 HeapWord* const beg_addr = space_info->dense_prefix(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3019 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
|
3020 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3021 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
|
3022 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
|
3023 const RegionData* cur_region; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3024 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
|
3025 HeapWord* const addr = cur_region->deferred_obj_addr(); |
0 | 3026 if (addr != NULL) { |
3027 if (start_array != NULL) { | |
3028 start_array->allocate_block(addr); | |
3029 } | |
3030 oop(addr)->update_contents(cm); | |
3031 assert(oop(addr)->is_oop_or_null(), "should be an oop now"); | |
3032 } | |
3033 } | |
3034 } | |
3035 | |
3036 // Skip over count live words starting from beg, and return the address of the | |
3037 // next live word. Unless marked, the word corresponding to beg is assumed to | |
3038 // be dead. Callers must either ensure beg does not correspond to the middle of | |
3039 // an object, or account for those live words in some other way. Callers must | |
3040 // also ensure that there are enough live words in the range [beg, end) to skip. | |
3041 HeapWord* | |
3042 PSParallelCompact::skip_live_words(HeapWord* beg, HeapWord* end, size_t count) | |
3043 { | |
3044 assert(count > 0, "sanity"); | |
3045 | |
3046 ParMarkBitMap* m = mark_bitmap(); | |
3047 idx_t bits_to_skip = m->words_to_bits(count); | |
3048 idx_t cur_beg = m->addr_to_bit(beg); | |
3049 const idx_t search_end = BitMap::word_align_up(m->addr_to_bit(end)); | |
3050 | |
3051 do { | |
3052 cur_beg = m->find_obj_beg(cur_beg, search_end); | |
3053 idx_t cur_end = m->find_obj_end(cur_beg, search_end); | |
3054 const size_t obj_bits = cur_end - cur_beg + 1; | |
3055 if (obj_bits > bits_to_skip) { | |
3056 return m->bit_to_addr(cur_beg + bits_to_skip); | |
3057 } | |
3058 bits_to_skip -= obj_bits; | |
3059 cur_beg = cur_end + 1; | |
3060 } while (bits_to_skip > 0); | |
3061 | |
3062 // Skipping the desired number of words landed just past the end of an object. | |
3063 // Find the start of the next object. | |
3064 cur_beg = m->find_obj_beg(cur_beg, search_end); | |
3065 assert(cur_beg < m->addr_to_bit(end), "not enough live words to skip"); | |
3066 return m->bit_to_addr(cur_beg); | |
3067 } | |
3068 | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3069 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
|
3070 SpaceId src_space_id, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3071 size_t src_region_idx) |
0 | 3072 { |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3073 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
|
3074 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3075 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
|
3076 if (split_info.dest_region_addr() == dest_addr) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3077 // 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
|
3078 // be copied to dest_addr. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3079 return split_info.first_src_addr(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3080 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3081 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3082 const ParallelCompactData& sd = summary_data(); |
0 | 3083 ParMarkBitMap* const bitmap = mark_bitmap(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3084 const size_t RegionSize = ParallelCompactData::RegionSize; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3085 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3086 assert(sd.is_region_aligned(dest_addr), "not aligned"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3087 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
|
3088 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
|
3089 HeapWord* const src_region_destination = src_region_ptr->destination(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3090 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3091 assert(dest_addr >= src_region_destination, "wrong src region"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3092 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
|
3093 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3094 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
|
3095 HeapWord* const src_region_end = src_region_beg + RegionSize; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3096 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3097 HeapWord* addr = src_region_beg; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3098 if (dest_addr == src_region_destination) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3099 // Return the first live word in the source region. |
0 | 3100 if (partial_obj_size == 0) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3101 addr = bitmap->find_obj_beg(addr, src_region_end); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3102 assert(addr < src_region_end, "no objects start in src region"); |
0 | 3103 } |
3104 return addr; | |
3105 } | |
3106 | |
3107 // Must skip some live data. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3108 size_t words_to_skip = dest_addr - src_region_destination; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3109 assert(src_region_ptr->data_size() > words_to_skip, "wrong src region"); |
0 | 3110 |
3111 if (partial_obj_size >= words_to_skip) { | |
3112 // All the live words to skip are part of the partial object. | |
3113 addr += words_to_skip; | |
3114 if (partial_obj_size == words_to_skip) { | |
3115 // Find the first live word past the partial object. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3116 addr = bitmap->find_obj_beg(addr, src_region_end); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3117 assert(addr < src_region_end, "wrong src region"); |
0 | 3118 } |
3119 return addr; | |
3120 } | |
3121 | |
3122 // Skip over the partial object (if any). | |
3123 if (partial_obj_size != 0) { | |
3124 words_to_skip -= partial_obj_size; | |
3125 addr += partial_obj_size; | |
3126 } | |
3127 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3128 // 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
|
3129 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
|
3130 assert(addr < src_region_end, "wrong src region"); |
0 | 3131 return addr; |
3132 } | |
3133 | |
3134 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
|
3135 SpaceId src_space_id, |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3136 size_t beg_region, |
0 | 3137 HeapWord* end_addr) |
3138 { | |
3139 ParallelCompactData& sd = summary_data(); | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3140 |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3141 #ifdef ASSERT |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3142 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
|
3143 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
|
3144 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
|
3145 "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
|
3146 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
|
3147 "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
|
3148 #endif // #ifdef ASSERT |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3149 |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3150 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
|
3151 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
|
3152 |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3153 // 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
|
3154 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
|
3155 RegionData* const enqueue_end = |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3156 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
|
3157 |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3158 for (RegionData* cur = beg; cur < end; ++cur) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3159 assert(cur->data_size() > 0, "region must have live data"); |
0 | 3160 cur->decrement_destination_count(); |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3161 if (cur < enqueue_end && cur->available() && cur->claim()) { |
1638 | 3162 cm->push_region(sd.region(cur)); |
0 | 3163 } |
3164 } | |
3165 } | |
3166 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3167 size_t PSParallelCompact::next_src_region(MoveAndUpdateClosure& closure, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3168 SpaceId& src_space_id, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3169 HeapWord*& src_space_top, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3170 HeapWord* end_addr) |
0 | 3171 { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3172 typedef ParallelCompactData::RegionData RegionData; |
0 | 3173 |
3174 ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3175 const size_t region_size = ParallelCompactData::RegionSize; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3176 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3177 size_t src_region_idx = 0; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3178 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3179 // 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
|
3180 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
|
3181 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
|
3182 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
|
3183 const RegionData* const top_region_ptr = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3184 sd.addr_to_region_ptr(top_aligned_up); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3185 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
|
3186 ++src_region_ptr; |
0 | 3187 } |
3188 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3189 if (src_region_ptr < top_region_ptr) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3190 // 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
|
3191 // and the source address to match src_region_ptr. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3192 src_region_idx = sd.region(src_region_ptr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3193 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
|
3194 if (src_region_addr > closure.source()) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3195 closure.set_source(src_region_addr); |
0 | 3196 } |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3197 return src_region_idx; |
0 | 3198 } |
3199 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3200 // Switch to a new source space and find the first non-empty region. |
0 | 3201 unsigned int space_id = src_space_id + 1; |
3202 assert(space_id < last_space_id, "not enough spaces"); | |
3203 | |
3204 HeapWord* const destination = closure.destination(); | |
3205 | |
3206 do { | |
3207 MutableSpace* space = _space_info[space_id].space(); | |
3208 HeapWord* const bottom = space->bottom(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3209 const RegionData* const bottom_cp = sd.addr_to_region_ptr(bottom); |
0 | 3210 |
3211 // Iterate over the spaces that do not compact into themselves. | |
3212 if (bottom_cp->destination() != bottom) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3213 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
|
3214 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
|
3215 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3216 for (const RegionData* src_cp = bottom_cp; src_cp < top_cp; ++src_cp) { |
0 | 3217 if (src_cp->live_obj_size() > 0) { |
3218 // Found it. | |
3219 assert(src_cp->destination() == destination, | |
3220 "first live obj in the space must match the destination"); | |
3221 assert(src_cp->partial_obj_size() == 0, | |
3222 "a space cannot begin with a partial obj"); | |
3223 | |
3224 src_space_id = SpaceId(space_id); | |
3225 src_space_top = space->top(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3226 const size_t src_region_idx = sd.region(src_cp); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3227 closure.set_source(sd.region_to_addr(src_region_idx)); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3228 return src_region_idx; |
0 | 3229 } else { |
3230 assert(src_cp->data_size() == 0, "sanity"); | |
3231 } | |
3232 } | |
3233 } | |
3234 } while (++space_id < last_space_id); | |
3235 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3236 assert(false, "no source region was found"); |
0 | 3237 return 0; |
3238 } | |
3239 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3240 void PSParallelCompact::fill_region(ParCompactionManager* cm, size_t region_idx) |
0 | 3241 { |
3242 typedef ParMarkBitMap::IterationStatus IterationStatus; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3243 const size_t RegionSize = ParallelCompactData::RegionSize; |
0 | 3244 ParMarkBitMap* const bitmap = mark_bitmap(); |
3245 ParallelCompactData& sd = summary_data(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3246 RegionData* const region_ptr = sd.region(region_idx); |
0 | 3247 |
3248 // Get the items needed to construct the closure. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3249 HeapWord* dest_addr = sd.region_to_addr(region_idx); |
0 | 3250 SpaceId dest_space_id = space_id(dest_addr); |
3251 ObjectStartArray* start_array = _space_info[dest_space_id].start_array(); | |
3252 HeapWord* new_top = _space_info[dest_space_id].new_top(); | |
3253 assert(dest_addr < new_top, "sanity"); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3254 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
|
3255 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3256 // Get the source region and related info. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3257 size_t src_region_idx = region_ptr->source_region(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3258 SpaceId src_space_id = space_id(sd.region_to_addr(src_region_idx)); |
0 | 3259 HeapWord* src_space_top = _space_info[src_space_id].space()->top(); |
3260 | |
3261 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
|
3262 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
|
3263 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3264 // 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
|
3265 // 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
|
3266 if (src_region_idx == region_idx) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3267 src_region_idx += 1; |
0 | 3268 } |
3269 | |
3270 if (bitmap->is_unmarked(closure.source())) { | |
3271 // The first source word is in the middle of an object; copy the remainder | |
3272 // of the object or as much as will fit. The fact that pointer updates were | |
3273 // deferred will be noted when the object header is processed. | |
3274 HeapWord* const old_src_addr = closure.source(); | |
3275 closure.copy_partial_obj(); | |
3276 if (closure.is_full()) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3277 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
|
3278 closure.source()); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3279 region_ptr->set_deferred_obj_addr(NULL); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3280 region_ptr->set_completed(); |
0 | 3281 return; |
3282 } | |
3283 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3284 HeapWord* const end_addr = sd.region_align_down(closure.source()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3285 if (sd.region_align_down(old_src_addr) != end_addr) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3286 // 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
|
3287 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
|
3288 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3289 // Move to the next source region, possibly switching spaces as well. All |
0 | 3290 // args except end_addr may be modified. |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3291 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
|
3292 end_addr); |
0 | 3293 } |
3294 } | |
3295 | |
3296 do { | |
3297 HeapWord* const cur_addr = closure.source(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3298 HeapWord* const end_addr = MIN2(sd.region_align_up(cur_addr + 1), |
0 | 3299 src_space_top); |
3300 IterationStatus status = bitmap->iterate(&closure, cur_addr, end_addr); | |
3301 | |
3302 if (status == ParMarkBitMap::incomplete) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3303 // 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
|
3304 // region. |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
1387
diff
changeset
|
3305 assert(closure.source() < end_addr, "sanity"); |
0 | 3306 HeapWord* const obj_beg = closure.source(); |
3307 HeapWord* const range_end = MIN2(obj_beg + closure.words_remaining(), | |
3308 src_space_top); | |
3309 HeapWord* const obj_end = bitmap->find_obj_end(obj_beg, range_end); | |
3310 if (obj_end < range_end) { | |
3311 // The end was found; the entire object will fit. | |
3312 status = closure.do_addr(obj_beg, bitmap->obj_size(obj_beg, obj_end)); | |
3313 assert(status != ParMarkBitMap::would_overflow, "sanity"); | |
3314 } else { | |
3315 // The end was not found; the object will not fit. | |
3316 assert(range_end < src_space_top, "obj cannot cross space boundary"); | |
3317 status = ParMarkBitMap::would_overflow; | |
3318 } | |
3319 } | |
3320 | |
3321 if (status == ParMarkBitMap::would_overflow) { | |
3322 // 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
|
3323 // 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
|
3324 region_ptr->set_deferred_obj_addr(closure.destination()); |
0 | 3325 status = closure.copy_until_full(); // copies from closure.source() |
3326 | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3327 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
|
3328 closure.source()); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3329 region_ptr->set_completed(); |
0 | 3330 return; |
3331 } | |
3332 | |
3333 if (status == ParMarkBitMap::full) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3334 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
|
3335 closure.source()); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3336 region_ptr->set_deferred_obj_addr(NULL); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3337 region_ptr->set_completed(); |
0 | 3338 return; |
3339 } | |
3340 | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3341 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
|
3342 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3343 // Move to the next source region, possibly switching spaces as well. All |
0 | 3344 // args except end_addr may be modified. |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3345 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
|
3346 end_addr); |
0 | 3347 } while (true); |
3348 } | |
3349 | |
3350 void | |
3351 PSParallelCompact::move_and_update(ParCompactionManager* cm, SpaceId space_id) { | |
3352 const MutableSpace* sp = space(space_id); | |
3353 if (sp->is_empty()) { | |
3354 return; | |
3355 } | |
3356 | |
3357 ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
3358 ParMarkBitMap* const bitmap = mark_bitmap(); | |
3359 HeapWord* const dp_addr = dense_prefix(space_id); | |
3360 HeapWord* beg_addr = sp->bottom(); | |
3361 HeapWord* end_addr = sp->top(); | |
3362 | |
3363 #ifdef ASSERT | |
3364 assert(beg_addr <= dp_addr && dp_addr <= end_addr, "bad dense prefix"); | |
3365 if (cm->should_verify_only()) { | |
3366 VerifyUpdateClosure verify_update(cm, sp); | |
3367 bitmap->iterate(&verify_update, beg_addr, end_addr); | |
3368 return; | |
3369 } | |
3370 | |
3371 if (cm->should_reset_only()) { | |
3372 ResetObjectsClosure reset_objects(cm); | |
3373 bitmap->iterate(&reset_objects, beg_addr, end_addr); | |
3374 return; | |
3375 } | |
3376 #endif | |
3377 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3378 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
|
3379 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
|
3380 if (beg_region < dp_region) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3381 update_and_deadwood_in_dense_prefix(cm, space_id, beg_region, dp_region); |
0 | 3382 } |
3383 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3384 // 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
|
3385 // 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
|
3386 HeapWord* const dest_addr = sd.partial_obj_end(dp_region); |
0 | 3387 HeapWord* const new_top = _space_info[space_id].new_top(); |
3388 assert(new_top >= dest_addr, "bad new_top value"); | |
3389 const size_t words = pointer_delta(new_top, dest_addr); | |
3390 | |
3391 if (words > 0) { | |
3392 ObjectStartArray* start_array = _space_info[space_id].start_array(); | |
3393 MoveAndUpdateClosure closure(bitmap, cm, start_array, dest_addr, words); | |
3394 | |
3395 ParMarkBitMap::IterationStatus status; | |
3396 status = bitmap->iterate(&closure, dest_addr, end_addr); | |
3397 assert(status == ParMarkBitMap::full, "iteration not complete"); | |
3398 assert(bitmap->find_obj_beg(closure.source(), end_addr) == end_addr, | |
3399 "live objects skipped because closure is full"); | |
3400 } | |
3401 } | |
3402 | |
3403 jlong PSParallelCompact::millis_since_last_gc() { | |
3404 jlong ret_val = os::javaTimeMillis() - _time_of_last_gc; | |
3405 // XXX See note in genCollectedHeap::millis_since_last_gc(). | |
3406 if (ret_val < 0) { | |
3407 NOT_PRODUCT(warning("time warp: %d", ret_val);) | |
3408 return 0; | |
3409 } | |
3410 return ret_val; | |
3411 } | |
3412 | |
3413 void PSParallelCompact::reset_millis_since_last_gc() { | |
3414 _time_of_last_gc = os::javaTimeMillis(); | |
3415 } | |
3416 | |
3417 ParMarkBitMap::IterationStatus MoveAndUpdateClosure::copy_until_full() | |
3418 { | |
3419 if (source() != destination()) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3420 DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());) |
0 | 3421 Copy::aligned_conjoint_words(source(), destination(), words_remaining()); |
3422 } | |
3423 update_state(words_remaining()); | |
3424 assert(is_full(), "sanity"); | |
3425 return ParMarkBitMap::full; | |
3426 } | |
3427 | |
3428 void MoveAndUpdateClosure::copy_partial_obj() | |
3429 { | |
3430 size_t words = words_remaining(); | |
3431 | |
3432 HeapWord* const range_end = MIN2(source() + words, bitmap()->region_end()); | |
3433 HeapWord* const end_addr = bitmap()->find_obj_end(source(), range_end); | |
3434 if (end_addr < range_end) { | |
3435 words = bitmap()->obj_size(source(), end_addr); | |
3436 } | |
3437 | |
3438 // This test is necessary; if omitted, the pointer updates to a partial object | |
3439 // that crosses the dense prefix boundary could be overwritten. | |
3440 if (source() != destination()) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3441 DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());) |
0 | 3442 Copy::aligned_conjoint_words(source(), destination(), words); |
3443 } | |
3444 update_state(words); | |
3445 } | |
3446 | |
3447 ParMarkBitMapClosure::IterationStatus | |
3448 MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) { | |
3449 assert(destination() != NULL, "sanity"); | |
3450 assert(bitmap()->obj_size(addr) == words, "bad size"); | |
3451 | |
3452 _source = addr; | |
3453 assert(PSParallelCompact::summary_data().calc_new_pointer(source()) == | |
3454 destination(), "wrong destination"); | |
3455 | |
3456 if (words > words_remaining()) { | |
3457 return ParMarkBitMap::would_overflow; | |
3458 } | |
3459 | |
3460 // The start_array must be updated even if the object is not moving. | |
3461 if (_start_array != NULL) { | |
3462 _start_array->allocate_block(destination()); | |
3463 } | |
3464 | |
3465 if (destination() != source()) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3466 DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());) |
0 | 3467 Copy::aligned_conjoint_words(source(), destination(), words); |
3468 } | |
3469 | |
3470 oop moved_oop = (oop) destination(); | |
3471 moved_oop->update_contents(compaction_manager()); | |
3472 assert(moved_oop->is_oop_or_null(), "Object should be whole at this point"); | |
3473 | |
3474 update_state(words); | |
3475 assert(destination() == (HeapWord*)moved_oop + moved_oop->size(), "sanity"); | |
3476 return is_full() ? ParMarkBitMap::full : ParMarkBitMap::incomplete; | |
3477 } | |
3478 | |
3479 UpdateOnlyClosure::UpdateOnlyClosure(ParMarkBitMap* mbm, | |
3480 ParCompactionManager* cm, | |
3481 PSParallelCompact::SpaceId space_id) : | |
3482 ParMarkBitMapClosure(mbm, cm), | |
3483 _space_id(space_id), | |
3484 _start_array(PSParallelCompact::start_array(space_id)) | |
3485 { | |
3486 } | |
3487 | |
3488 // Updates the references in the object to their new values. | |
3489 ParMarkBitMapClosure::IterationStatus | |
3490 UpdateOnlyClosure::do_addr(HeapWord* addr, size_t words) { | |
3491 do_addr(addr); | |
3492 return ParMarkBitMap::incomplete; | |
3493 } | |
3494 | |
3495 // Verify the new location using the forwarding pointer | |
3496 // from MarkSweep::mark_sweep_phase2(). Set the mark_word | |
3497 // to the initial value. | |
3498 ParMarkBitMapClosure::IterationStatus | |
3499 PSParallelCompact::VerifyUpdateClosure::do_addr(HeapWord* addr, size_t words) { | |
3500 // The second arg (words) is not used. | |
3501 oop obj = (oop) addr; | |
3502 HeapWord* forwarding_ptr = (HeapWord*) obj->mark()->decode_pointer(); | |
3503 HeapWord* new_pointer = summary_data().calc_new_pointer(obj); | |
3504 if (forwarding_ptr == NULL) { | |
3505 // The object is dead or not moving. | |
3506 assert(bitmap()->is_unmarked(obj) || (new_pointer == (HeapWord*) obj), | |
3507 "Object liveness is wrong."); | |
3508 return ParMarkBitMap::incomplete; | |
3509 } | |
3251
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
3510 assert(HeapMaximumCompactionInterval > 1 || MarkSweepAlwaysCompactCount > 1 || |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
3511 forwarding_ptr == new_pointer, "new location is incorrect"); |
0 | 3512 return ParMarkBitMap::incomplete; |
3513 } | |
3514 | |
3515 // Reset objects modified for debug checking. | |
3516 ParMarkBitMapClosure::IterationStatus | |
3517 PSParallelCompact::ResetObjectsClosure::do_addr(HeapWord* addr, size_t words) { | |
3518 // The second arg (words) is not used. | |
3519 oop obj = (oop) addr; | |
3520 obj->init_mark(); | |
3521 return ParMarkBitMap::incomplete; | |
3522 } | |
3523 | |
3524 // Prepare for compaction. This method is executed once | |
3525 // (i.e., by a single thread) before compaction. | |
3526 // Save the updated location of the intArrayKlassObj for | |
3527 // filling holes in the dense prefix. | |
3528 void PSParallelCompact::compact_prologue() { | |
3529 _updated_int_array_klass_obj = (klassOop) | |
3530 summary_data().calc_new_pointer(Universe::intArrayKlassObj()); | |
3531 } | |
3532 |