Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @ 3772:6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
Summary: Perform a heap verification after the first phase of G1's full GC using objects' mark words to determine liveness. The third parameter of the heap verification routines, which was used in G1 to determine which marking bitmap to use in liveness calculations, has been changed from a boolean to an enum with values defined for using the mark word, and the 'prev' and 'next' bitmaps.
Reviewed-by: tonyp, ysr
author | johnc |
---|---|
date | Tue, 14 Jun 2011 11:01:10 -0700 |
parents | 78542e2b5e35 |
children | c2bf0120ee5d |
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 NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); | |
2073 COMPILER2_PRESENT(DerivedPointerTable::clear()); | |
2074 | |
2075 ref_processor()->enable_discovery(); | |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
2076 ref_processor()->setup_policy(maximum_heap_compaction); |
0 | 2077 |
2078 bool marked_for_unloading = false; | |
2079 | |
2080 marking_start.update(); | |
210 | 2081 marking_phase(vmthread_cm, maximum_heap_compaction); |
0 | 2082 |
2083 #ifndef PRODUCT | |
2084 if (TraceParallelOldGCMarkingPhase) { | |
2085 gclog_or_tty->print_cr("marking_phase: cas_tries %d cas_retries %d " | |
2086 "cas_by_another %d", | |
2087 mark_bitmap()->cas_tries(), mark_bitmap()->cas_retries(), | |
2088 mark_bitmap()->cas_by_another()); | |
2089 } | |
2090 #endif // #ifndef PRODUCT | |
2091 | |
2092 bool max_on_system_gc = UseMaximumCompactionOnSystemGC && is_system_gc; | |
210 | 2093 summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc); |
0 | 2094 |
2095 COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity")); | |
2096 COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); | |
2097 | |
2098 // adjust_roots() updates Universe::_intArrayKlassObj which is | |
2099 // needed by the compaction for filling holes in the dense prefix. | |
2100 adjust_roots(); | |
2101 | |
2102 compaction_start.update(); | |
2103 // Does the perm gen always have to be done serially because | |
2104 // klasses are used in the update of an object? | |
210 | 2105 compact_perm(vmthread_cm); |
0 | 2106 |
3251
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2107 compact(); |
0 | 2108 |
2109 // Reset the mark bitmap, summary data, and do other bookkeeping. Must be | |
2110 // done before resizing. | |
2111 post_compact(); | |
2112 | |
2113 // Let the size policy know we're done | |
2114 size_policy->major_collection_end(old_gen->used_in_bytes(), gc_cause); | |
2115 | |
2116 if (UseAdaptiveSizePolicy) { | |
2117 if (PrintAdaptiveSizePolicy) { | |
2118 gclog_or_tty->print("AdaptiveSizeStart: "); | |
2119 gclog_or_tty->stamp(); | |
2120 gclog_or_tty->print_cr(" collection: %d ", | |
2121 heap->total_collections()); | |
2122 if (Verbose) { | |
2123 gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d" | |
2124 " perm_gen_capacity: %d ", | |
2125 old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes(), | |
2126 perm_gen->capacity_in_bytes()); | |
2127 } | |
2128 } | |
2129 | |
2130 // Don't check if the size_policy is ready here. Let | |
2131 // the size_policy check that internally. | |
2132 if (UseAdaptiveGenerationSizePolicyAtMajorCollection && | |
2133 ((gc_cause != GCCause::_java_lang_system_gc) || | |
2134 UseAdaptiveSizePolicyWithSystemGC)) { | |
2135 // Calculate optimal free space amounts | |
2136 assert(young_gen->max_size() > | |
2137 young_gen->from_space()->capacity_in_bytes() + | |
2138 young_gen->to_space()->capacity_in_bytes(), | |
2139 "Sizes of space in young gen are out-of-bounds"); | |
2140 size_t max_eden_size = young_gen->max_size() - | |
2141 young_gen->from_space()->capacity_in_bytes() - | |
2142 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
|
2143 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
|
2144 young_gen->used_in_bytes(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2145 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
|
2146 old_gen->used_in_bytes(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2147 perm_gen->used_in_bytes(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2148 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
|
2149 old_gen->max_gen_size(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2150 max_eden_size, |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2151 true /* full gc*/, |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
2152 gc_cause, |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1311
diff
changeset
|
2153 heap->collector_policy()); |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2154 |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2155 heap->resize_old_gen( |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2156 size_policy->calculated_old_free_size_in_bytes()); |
0 | 2157 |
2158 // Don't resize the young generation at an major collection. A | |
2159 // desired young generation size may have been calculated but | |
2160 // resizing the young generation complicates the code because the | |
2161 // resizing of the old generation may have moved the boundary | |
2162 // between the young generation and the old generation. Let the | |
2163 // young generation resizing happen at the minor collections. | |
2164 } | |
2165 if (PrintAdaptiveSizePolicy) { | |
2166 gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ", | |
2167 heap->total_collections()); | |
2168 } | |
2169 } | |
2170 | |
2171 if (UsePerfData) { | |
2172 PSGCAdaptivePolicyCounters* const counters = heap->gc_policy_counters(); | |
2173 counters->update_counters(); | |
2174 counters->update_old_capacity(old_gen->capacity_in_bytes()); | |
2175 counters->update_young_capacity(young_gen->capacity_in_bytes()); | |
2176 } | |
2177 | |
2178 heap->resize_all_tlabs(); | |
2179 | |
2180 // We collected the perm gen, so we'll resize it here. | |
2181 perm_gen->compute_new_size(pre_gc_values.perm_gen_used()); | |
2182 | |
2183 if (TraceGen1Time) accumulated_time()->stop(); | |
2184 | |
2185 if (PrintGC) { | |
2186 if (PrintGCDetails) { | |
2187 // No GC timestamp here. This is after GC so it would be confusing. | |
2188 young_gen->print_used_change(pre_gc_values.young_gen_used()); | |
2189 old_gen->print_used_change(pre_gc_values.old_gen_used()); | |
2190 heap->print_heap_change(pre_gc_values.heap_used()); | |
2191 // Print perm gen last (print_heap_change() excludes the perm gen). | |
2192 perm_gen->print_used_change(pre_gc_values.perm_gen_used()); | |
2193 } else { | |
2194 heap->print_heap_change(pre_gc_values.heap_used()); | |
2195 } | |
2196 } | |
2197 | |
2198 // Track memory usage and detect low memory | |
2199 MemoryService::track_memory_usage(); | |
2200 heap->update_counters(); | |
2201 } | |
2202 | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2203 #ifdef ASSERT |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2204 for (size_t i = 0; i < ParallelGCThreads + 1; ++i) { |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2205 ParCompactionManager* const cm = |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2206 ParCompactionManager::manager_array(int(i)); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2207 assert(cm->marking_stack()->is_empty(), "should be empty"); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2208 assert(cm->region_stack()->is_empty(), "should be empty"); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2209 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
|
2210 } |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2211 #endif // ASSERT |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2212 |
0 | 2213 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) { |
2214 HandleMark hm; // Discard invalid handles created during verification | |
2215 gclog_or_tty->print(" VerifyAfterGC:"); | |
2216 Universe::verify(false); | |
2217 } | |
2218 | |
2219 // Re-verify object start arrays | |
2220 if (VerifyObjectStartArray && | |
2221 VerifyAfterGC) { | |
2222 old_gen->verify_object_start_array(); | |
2223 perm_gen->verify_object_start_array(); | |
2224 } | |
2225 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2226 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2227 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
|
2228 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
|
2229 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
210
diff
changeset
|
2230 |
0 | 2231 NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); |
2232 | |
2233 collection_exit.update(); | |
2234 | |
2235 if (PrintHeapAtGC) { | |
2236 Universe::print_heap_after_gc(); | |
2237 } | |
2238 if (PrintGCTaskTimeStamps) { | |
2239 gclog_or_tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " " | |
2240 INT64_FORMAT, | |
2241 marking_start.ticks(), compaction_start.ticks(), | |
2242 collection_exit.ticks()); | |
2243 gc_task_manager()->print_task_time_stamps(); | |
2244 } | |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
496
diff
changeset
|
2245 |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
2246 heap->post_full_gc_dump(); |
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
2247 |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
496
diff
changeset
|
2248 #ifdef TRACESPINNING |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
496
diff
changeset
|
2249 ParallelTaskTerminator::print_termination_counts(); |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
496
diff
changeset
|
2250 #endif |
0 | 2251 } |
2252 | |
2253 bool PSParallelCompact::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy, | |
2254 PSYoungGen* young_gen, | |
2255 PSOldGen* old_gen) { | |
2256 MutableSpace* const eden_space = young_gen->eden_space(); | |
2257 assert(!eden_space->is_empty(), "eden must be non-empty"); | |
2258 assert(young_gen->virtual_space()->alignment() == | |
2259 old_gen->virtual_space()->alignment(), "alignments do not match"); | |
2260 | |
2261 if (!(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary)) { | |
2262 return false; | |
2263 } | |
2264 | |
2265 // Both generations must be completely committed. | |
2266 if (young_gen->virtual_space()->uncommitted_size() != 0) { | |
2267 return false; | |
2268 } | |
2269 if (old_gen->virtual_space()->uncommitted_size() != 0) { | |
2270 return false; | |
2271 } | |
2272 | |
2273 // Figure out how much to take from eden. Include the average amount promoted | |
2274 // in the total; otherwise the next young gen GC will simply bail out to a | |
2275 // full GC. | |
2276 const size_t alignment = old_gen->virtual_space()->alignment(); | |
2277 const size_t eden_used = eden_space->used_in_bytes(); | |
2278 const size_t promoted = (size_t)size_policy->avg_promoted()->padded_average(); | |
2279 const size_t absorb_size = align_size_up(eden_used + promoted, alignment); | |
2280 const size_t eden_capacity = eden_space->capacity_in_bytes(); | |
2281 | |
2282 if (absorb_size >= eden_capacity) { | |
2283 return false; // Must leave some space in eden. | |
2284 } | |
2285 | |
2286 const size_t new_young_size = young_gen->capacity_in_bytes() - absorb_size; | |
2287 if (new_young_size < young_gen->min_gen_size()) { | |
2288 return false; // Respect young gen minimum size. | |
2289 } | |
2290 | |
2291 if (TraceAdaptiveGCBoundary && Verbose) { | |
2292 gclog_or_tty->print(" absorbing " SIZE_FORMAT "K: " | |
2293 "eden " SIZE_FORMAT "K->" SIZE_FORMAT "K " | |
2294 "from " SIZE_FORMAT "K, to " SIZE_FORMAT "K " | |
2295 "young_gen " SIZE_FORMAT "K->" SIZE_FORMAT "K ", | |
2296 absorb_size / K, | |
2297 eden_capacity / K, (eden_capacity - absorb_size) / K, | |
2298 young_gen->from_space()->used_in_bytes() / K, | |
2299 young_gen->to_space()->used_in_bytes() / K, | |
2300 young_gen->capacity_in_bytes() / K, new_young_size / K); | |
2301 } | |
2302 | |
2303 // Fill the unused part of the old gen. | |
2304 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
|
2305 HeapWord* const unused_start = old_space->top(); |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2306 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
|
2307 |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2308 if (unused_words > 0) { |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2309 if (unused_words < CollectedHeap::min_fill_size()) { |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2310 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
|
2311 } |
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
2312 CollectedHeap::fill_with_objects(unused_start, unused_words); |
0 | 2313 } |
2314 | |
2315 // Take the live data from eden and set both top and end in the old gen to | |
2316 // eden top. (Need to set end because reset_after_change() mangles the region | |
2317 // from end to virtual_space->high() in debug builds). | |
2318 HeapWord* const new_top = eden_space->top(); | |
2319 old_gen->virtual_space()->expand_into(young_gen->virtual_space(), | |
2320 absorb_size); | |
2321 young_gen->reset_after_change(); | |
2322 old_space->set_top(new_top); | |
2323 old_space->set_end(new_top); | |
2324 old_gen->reset_after_change(); | |
2325 | |
2326 // Update the object start array for the filler object and the data from eden. | |
2327 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
|
2328 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
|
2329 start_array->allocate_block(p); |
0 | 2330 } |
2331 | |
2332 // Could update the promoted average here, but it is not typically updated at | |
2333 // full GCs and the value to use is unclear. Something like | |
2334 // | |
2335 // cur_promoted_avg + absorb_size / number_of_scavenges_since_last_full_gc. | |
2336 | |
2337 size_policy->set_bytes_absorbed_from_eden(absorb_size); | |
2338 return true; | |
2339 } | |
2340 | |
2341 GCTaskManager* const PSParallelCompact::gc_task_manager() { | |
2342 assert(ParallelScavengeHeap::gc_task_manager() != NULL, | |
2343 "shouldn't return NULL"); | |
2344 return ParallelScavengeHeap::gc_task_manager(); | |
2345 } | |
2346 | |
2347 void PSParallelCompact::marking_phase(ParCompactionManager* cm, | |
2348 bool maximum_heap_compaction) { | |
2349 // Recursively traverse all live objects and mark them | |
2350 EventMark m("1 mark object"); | |
2351 TraceTime tm("marking phase", print_phases(), true, gclog_or_tty); | |
2352 | |
2353 ParallelScavengeHeap* heap = gc_heap(); | |
2354 uint parallel_gc_threads = heap->gc_task_manager()->workers(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2355 TaskQueueSetSuper* qset = ParCompactionManager::region_array(); |
0 | 2356 ParallelTaskTerminator terminator(parallel_gc_threads, qset); |
2357 | |
2358 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); | |
2359 PSParallelCompact::FollowStackClosure follow_stack_closure(cm); | |
2360 | |
2361 { | |
2362 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
|
2363 ParallelScavengeHeap::ParStrongRootsScope psrs; |
0 | 2364 |
2365 GCTaskQueue* q = GCTaskQueue::create(); | |
2366 | |
2367 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::universe)); | |
2368 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jni_handles)); | |
2369 // We scan the thread roots in parallel | |
2370 Threads::create_thread_roots_marking_tasks(q); | |
2371 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::object_synchronizer)); | |
2372 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::flat_profiler)); | |
2373 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management)); | |
2374 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary)); | |
2375 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti)); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
696
diff
changeset
|
2376 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache)); |
0 | 2377 |
2378 if (parallel_gc_threads > 1) { | |
2379 for (uint j = 0; j < parallel_gc_threads; j++) { | |
2380 q->enqueue(new StealMarkingTask(&terminator)); | |
2381 } | |
2382 } | |
2383 | |
2384 WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create(); | |
2385 q->enqueue(fin); | |
2386 | |
2387 gc_task_manager()->add_list(q); | |
2388 | |
2389 fin->wait_for(); | |
2390 | |
2391 // We have to release the barrier tasks! | |
2392 WaitForBarrierGCTask::destroy(fin); | |
2393 } | |
2394 | |
2395 // Process reference objects found during marking | |
2396 { | |
2397 TraceTime tm_r("reference processing", print_phases(), true, gclog_or_tty); | |
2398 if (ref_processor()->processing_is_mt()) { | |
2399 RefProcTaskExecutor task_executor; | |
2400 ref_processor()->process_discovered_references( | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
376
diff
changeset
|
2401 is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, |
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
376
diff
changeset
|
2402 &task_executor); |
0 | 2403 } else { |
2404 ref_processor()->process_discovered_references( | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
376
diff
changeset
|
2405 is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL); |
0 | 2406 } |
2407 } | |
2408 | |
2409 TraceTime tm_c("class unloading", print_phases(), true, gclog_or_tty); | |
2410 // Follow system dictionary roots and unload classes. | |
2411 bool purged_class = SystemDictionary::do_unloading(is_alive_closure()); | |
2412 | |
2413 // Follow code cache roots. | |
2414 CodeCache::do_unloading(is_alive_closure(), &mark_and_push_closure, | |
2415 purged_class); | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
997
diff
changeset
|
2416 cm->follow_marking_stacks(); // Flush marking stack. |
0 | 2417 |
2418 // Update subklass/sibling/implementor links of live klasses | |
2419 // revisit_klass_stack is used in follow_weak_klass_links(). | |
941 | 2420 follow_weak_klass_links(); |
2421 | |
2422 // Revisit memoized MDO's and clear any unmarked weak refs | |
2423 follow_mdo_weak_refs(); | |
0 | 2424 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
2425 // Visit interned string tables and delete unmarked oops |
0 | 2426 StringTable::unlink(is_alive_closure()); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
2427 // Clean up unreferenced symbols in symbol table. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
2428 SymbolTable::unlink(); |
0 | 2429 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
997
diff
changeset
|
2430 assert(cm->marking_stacks_empty(), "marking stacks should be empty"); |
0 | 2431 } |
2432 | |
2433 // This should be moved to the shared markSweep code! | |
2434 class PSAlwaysTrueClosure: public BoolObjectClosure { | |
2435 public: | |
2436 void do_object(oop p) { ShouldNotReachHere(); } | |
2437 bool do_object_b(oop p) { return true; } | |
2438 }; | |
2439 static PSAlwaysTrueClosure always_true; | |
2440 | |
2441 void PSParallelCompact::adjust_roots() { | |
2442 // Adjust the pointers to reflect the new locations | |
2443 EventMark m("3 adjust roots"); | |
2444 TraceTime tm("adjust roots", print_phases(), true, gclog_or_tty); | |
2445 | |
2446 // General strong roots. | |
2447 Universe::oops_do(adjust_root_pointer_closure()); | |
2448 ReferenceProcessor::oops_do(adjust_root_pointer_closure()); | |
2449 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
|
2450 Threads::oops_do(adjust_root_pointer_closure(), NULL); |
0 | 2451 ObjectSynchronizer::oops_do(adjust_root_pointer_closure()); |
2452 FlatProfiler::oops_do(adjust_root_pointer_closure()); | |
2453 Management::oops_do(adjust_root_pointer_closure()); | |
2454 JvmtiExport::oops_do(adjust_root_pointer_closure()); | |
2455 // SO_AllClasses | |
2456 SystemDictionary::oops_do(adjust_root_pointer_closure()); | |
2457 | |
2458 // Now adjust pointers in remaining weak roots. (All of which should | |
2459 // have been cleared if they pointed to non-surviving objects.) | |
2460 // Global (weak) JNI handles | |
2461 JNIHandles::weak_oops_do(&always_true, adjust_root_pointer_closure()); | |
2462 | |
2463 CodeCache::oops_do(adjust_pointer_closure()); | |
2464 StringTable::oops_do(adjust_root_pointer_closure()); | |
2465 ref_processor()->weak_oops_do(adjust_root_pointer_closure()); | |
2466 // Roots were visited so references into the young gen in roots | |
2467 // may have been scanned. Process them also. | |
2468 // Should the reference processor have a span that excludes | |
2469 // young gen objects? | |
2470 PSScavenge::reference_processor()->weak_oops_do( | |
2471 adjust_root_pointer_closure()); | |
2472 } | |
2473 | |
2474 void PSParallelCompact::compact_perm(ParCompactionManager* cm) { | |
2475 EventMark m("4 compact perm"); | |
2476 TraceTime tm("compact perm gen", print_phases(), true, gclog_or_tty); | |
2477 // trace("4"); | |
2478 | |
2479 gc_heap()->perm_gen()->start_array()->reset(); | |
2480 move_and_update(cm, perm_space_id); | |
2481 } | |
2482 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2483 void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2484 uint parallel_gc_threads) |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2485 { |
0 | 2486 TraceTime tm("drain task setup", print_phases(), true, gclog_or_tty); |
2487 | |
2488 const unsigned int task_count = MAX2(parallel_gc_threads, 1U); | |
2489 for (unsigned int j = 0; j < task_count; j++) { | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1638
diff
changeset
|
2490 q->enqueue(new DrainStacksCompactionTask(j)); |
0 | 2491 } |
2492 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2493 // Find all regions that are available (can be filled immediately) and |
0 | 2494 // 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
|
2495 // order (high to low) so the regions will be removed in ascending order. |
0 | 2496 |
2497 const ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
2498 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2499 size_t fillable_regions = 0; // A count for diagnostic purposes. |
0 | 2500 unsigned int which = 0; // The worker thread number. |
2501 | |
2502 for (unsigned int id = to_space_id; id > perm_space_id; --id) { | |
2503 SpaceInfo* const space_info = _space_info + id; | |
2504 MutableSpace* const space = space_info->space(); | |
2505 HeapWord* const new_top = space_info->new_top(); | |
2506 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2507 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
|
2508 const size_t end_region = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2509 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
|
2510 assert(end_region > 0, "perm gen cannot be empty"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2511 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2512 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
|
2513 if (sd.region(cur)->claim_unsafe()) { |
0 | 2514 ParCompactionManager* cm = ParCompactionManager::manager_array(which); |
1638 | 2515 cm->push_region(cur); |
0 | 2516 |
2517 if (TraceParallelOldGCCompactionPhase && Verbose) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2518 const size_t count_mod_8 = fillable_regions & 7; |
0 | 2519 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
|
2520 gclog_or_tty->print(" " SIZE_FORMAT_W(7), cur); |
0 | 2521 if (count_mod_8 == 7) gclog_or_tty->cr(); |
2522 } | |
2523 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2524 NOT_PRODUCT(++fillable_regions;) |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2525 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2526 // Assign regions to threads in round-robin fashion. |
0 | 2527 if (++which == task_count) { |
2528 which = 0; | |
2529 } | |
2530 } | |
2531 } | |
2532 } | |
2533 | |
2534 if (TraceParallelOldGCCompactionPhase) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2535 if (Verbose && (fillable_regions & 7) != 0) gclog_or_tty->cr(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2536 gclog_or_tty->print_cr("%u initially fillable regions", fillable_regions); |
0 | 2537 } |
2538 } | |
2539 | |
2540 #define PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING 4 | |
2541 | |
2542 void PSParallelCompact::enqueue_dense_prefix_tasks(GCTaskQueue* q, | |
2543 uint parallel_gc_threads) { | |
2544 TraceTime tm("dense prefix task setup", print_phases(), true, gclog_or_tty); | |
2545 | |
2546 ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
2547 | |
2548 // Iterate over all the spaces adding tasks for updating | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2549 // regions in the dense prefix. Assume that 1 gc thread |
0 | 2550 // will work on opening the gaps and the remaining gc threads |
2551 // will work on the dense prefix. | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2552 unsigned int space_id; |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2553 for (space_id = old_space_id; space_id < last_space_id; ++ space_id) { |
0 | 2554 HeapWord* const dense_prefix_end = _space_info[space_id].dense_prefix(); |
2555 const MutableSpace* const space = _space_info[space_id].space(); | |
2556 | |
2557 if (dense_prefix_end == space->bottom()) { | |
2558 // There is no dense prefix for this space. | |
2559 continue; | |
2560 } | |
2561 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2562 // The dense prefix is before this region. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2563 size_t region_index_end_dense_prefix = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2564 sd.addr_to_region_idx(dense_prefix_end); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2565 RegionData* const dense_prefix_cp = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2566 sd.region(region_index_end_dense_prefix); |
0 | 2567 assert(dense_prefix_end == space->end() || |
2568 dense_prefix_cp->available() || | |
2569 dense_prefix_cp->claimed(), | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2570 "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
|
2571 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2572 size_t region_index_start = sd.addr_to_region_idx(space->bottom()); |
0 | 2573 |
2574 // Is there dense prefix work? | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2575 size_t total_dense_prefix_regions = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2576 region_index_end_dense_prefix - region_index_start; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2577 // How many regions of the dense prefix should be given to |
0 | 2578 // each thread? |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2579 if (total_dense_prefix_regions > 0) { |
0 | 2580 uint tasks_for_dense_prefix = 1; |
3251
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2581 if (total_dense_prefix_regions <= |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2582 (parallel_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING)) { |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2583 // Don't over partition. This assumes that |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2584 // PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING is a small integer value |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2585 // so there are not many regions to process. |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2586 tasks_for_dense_prefix = parallel_gc_threads; |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2587 } else { |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2588 // Over partition |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2589 tasks_for_dense_prefix = parallel_gc_threads * |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
2590 PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING; |
0 | 2591 } |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2592 size_t regions_per_thread = total_dense_prefix_regions / |
0 | 2593 tasks_for_dense_prefix; |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2594 // Give each thread at least 1 region. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2595 if (regions_per_thread == 0) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2596 regions_per_thread = 1; |
0 | 2597 } |
2598 | |
2599 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
|
2600 if (region_index_start >= region_index_end_dense_prefix) { |
0 | 2601 break; |
2602 } | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2603 // region_index_end is not processed |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2604 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
|
2605 region_index_end_dense_prefix); |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2606 q->enqueue(new UpdateDensePrefixTask(SpaceId(space_id), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2607 region_index_start, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2608 region_index_end)); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2609 region_index_start = region_index_end; |
0 | 2610 } |
2611 } | |
2612 // This gets any part of the dense prefix that did not | |
2613 // fit evenly. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2614 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
|
2615 q->enqueue(new UpdateDensePrefixTask(SpaceId(space_id), |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2616 region_index_start, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2617 region_index_end_dense_prefix)); |
0 | 2618 } |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
2619 } |
0 | 2620 } |
2621 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2622 void PSParallelCompact::enqueue_region_stealing_tasks( |
0 | 2623 GCTaskQueue* q, |
2624 ParallelTaskTerminator* terminator_ptr, | |
2625 uint parallel_gc_threads) { | |
2626 TraceTime tm("steal task setup", print_phases(), true, gclog_or_tty); | |
2627 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2628 // Once a thread has drained it's stack, it should try to steal regions from |
0 | 2629 // other threads. |
2630 if (parallel_gc_threads > 1) { | |
2631 for (uint j = 0; j < parallel_gc_threads; j++) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2632 q->enqueue(new StealRegionCompactionTask(terminator_ptr)); |
0 | 2633 } |
2634 } | |
2635 } | |
2636 | |
2637 void PSParallelCompact::compact() { | |
2638 EventMark m("5 compact"); | |
2639 // trace("5"); | |
2640 TraceTime tm("compaction phase", print_phases(), true, gclog_or_tty); | |
2641 | |
2642 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
2643 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
2644 PSOldGen* old_gen = heap->old_gen(); | |
2645 old_gen->start_array()->reset(); | |
2646 uint parallel_gc_threads = heap->gc_task_manager()->workers(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2647 TaskQueueSetSuper* qset = ParCompactionManager::region_array(); |
0 | 2648 ParallelTaskTerminator terminator(parallel_gc_threads, qset); |
2649 | |
2650 GCTaskQueue* q = GCTaskQueue::create(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2651 enqueue_region_draining_tasks(q, parallel_gc_threads); |
0 | 2652 enqueue_dense_prefix_tasks(q, parallel_gc_threads); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2653 enqueue_region_stealing_tasks(q, &terminator, parallel_gc_threads); |
0 | 2654 |
2655 { | |
2656 TraceTime tm_pc("par compact", print_phases(), true, gclog_or_tty); | |
2657 | |
2658 WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create(); | |
2659 q->enqueue(fin); | |
2660 | |
2661 gc_task_manager()->add_list(q); | |
2662 | |
2663 fin->wait_for(); | |
2664 | |
2665 // We have to release the barrier tasks! | |
2666 WaitForBarrierGCTask::destroy(fin); | |
2667 | |
2668 #ifdef ASSERT | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2669 // Verify that all regions have been processed before the deferred updates. |
0 | 2670 // 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
|
2671 // valid until the perm gen is compacted by regions. |
0 | 2672 for (unsigned int id = old_space_id; id < last_space_id; ++id) { |
2673 verify_complete(SpaceId(id)); | |
2674 } | |
2675 #endif | |
2676 } | |
2677 | |
2678 { | |
2679 // Update the deferred objects, if any. Any compaction manager can be used. | |
2680 TraceTime tm_du("deferred updates", print_phases(), true, gclog_or_tty); | |
2681 ParCompactionManager* cm = ParCompactionManager::manager_array(0); | |
2682 for (unsigned int id = old_space_id; id < last_space_id; ++id) { | |
2683 update_deferred_objects(cm, SpaceId(id)); | |
2684 } | |
2685 } | |
2686 } | |
2687 | |
2688 #ifdef ASSERT | |
2689 void PSParallelCompact::verify_complete(SpaceId space_id) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2690 // 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
|
2691 // and all Regions between new_top() and top() should be available (i.e., |
0 | 2692 // should have been emptied). |
2693 ParallelCompactData& sd = summary_data(); | |
2694 SpaceInfo si = _space_info[space_id]; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2695 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
|
2696 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
|
2697 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
|
2698 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
|
2699 const size_t old_top_region = sd.addr_to_region_idx(old_top_addr); |
0 | 2700 |
2701 bool issued_a_warning = false; | |
2702 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2703 size_t cur_region; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2704 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
|
2705 const RegionData* const c = sd.region(cur_region); |
0 | 2706 if (!c->completed()) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2707 warning("region " SIZE_FORMAT " not filled: " |
0 | 2708 "destination_count=" SIZE_FORMAT, |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2709 cur_region, c->destination_count()); |
0 | 2710 issued_a_warning = true; |
2711 } | |
2712 } | |
2713 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2714 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
|
2715 const RegionData* const c = sd.region(cur_region); |
0 | 2716 if (!c->available()) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2717 warning("region " SIZE_FORMAT " not empty: " |
0 | 2718 "destination_count=" SIZE_FORMAT, |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2719 cur_region, c->destination_count()); |
0 | 2720 issued_a_warning = true; |
2721 } | |
2722 } | |
2723 | |
2724 if (issued_a_warning) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2725 print_region_ranges(); |
0 | 2726 } |
2727 } | |
2728 #endif // #ifdef ASSERT | |
2729 | |
2730 void | |
941 | 2731 PSParallelCompact::follow_weak_klass_links() { |
0 | 2732 // All klasses on the revisit stack are marked at this point. |
2733 // Update and follow all subklass, sibling and implementor links. | |
941 | 2734 if (PrintRevisitStats) { |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2735 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
|
2736 SystemDictionary::number_of_classes()); |
941 | 2737 } |
2738 for (uint i = 0; i < ParallelGCThreads + 1; i++) { | |
0 | 2739 ParCompactionManager* cm = ParCompactionManager::manager_array(i); |
2740 KeepAliveClosure keep_alive_closure(cm); | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2741 Stack<Klass*>* const rks = cm->revisit_klass_stack(); |
941 | 2742 if (PrintRevisitStats) { |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2743 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
|
2744 i, rks->size()); |
941 | 2745 } |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2746 while (!rks->is_empty()) { |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2747 Klass* const k = rks->pop(); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2748 k->follow_weak_klass_links(is_alive_closure(), &keep_alive_closure); |
0 | 2749 } |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2750 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
997
diff
changeset
|
2751 cm->follow_marking_stacks(); |
0 | 2752 } |
2753 } | |
2754 | |
2755 void | |
2756 PSParallelCompact::revisit_weak_klass_link(ParCompactionManager* cm, Klass* k) { | |
2757 cm->revisit_klass_stack()->push(k); | |
2758 } | |
2759 | |
941 | 2760 void PSParallelCompact::revisit_mdo(ParCompactionManager* cm, DataLayout* p) { |
2761 cm->revisit_mdo_stack()->push(p); | |
2762 } | |
2763 | |
2764 void PSParallelCompact::follow_mdo_weak_refs() { | |
2765 // All strongly reachable oops have been marked at this point; | |
2766 // we can visit and clear any weak references from MDO's which | |
2767 // we memoized during the strong marking phase. | |
2768 if (PrintRevisitStats) { | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2769 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
|
2770 SystemDictionary::number_of_classes()); |
941 | 2771 } |
2772 for (uint i = 0; i < ParallelGCThreads + 1; i++) { | |
2773 ParCompactionManager* cm = ParCompactionManager::manager_array(i); | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2774 Stack<DataLayout*>* rms = cm->revisit_mdo_stack(); |
941 | 2775 if (PrintRevisitStats) { |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2776 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
|
2777 i, rms->size()); |
941 | 2778 } |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2779 while (!rms->is_empty()) { |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2780 rms->pop()->follow_weak_refs(is_alive_closure()); |
941 | 2781 } |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1833
diff
changeset
|
2782 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
997
diff
changeset
|
2783 cm->follow_marking_stacks(); |
941 | 2784 } |
2785 } | |
2786 | |
2787 | |
0 | 2788 #ifdef VALIDATE_MARK_SWEEP |
2789 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
2790 void PSParallelCompact::track_adjusted_pointer(void* p, bool isroot) { |
0 | 2791 if (!ValidateMarkSweep) |
2792 return; | |
2793 | |
2794 if (!isroot) { | |
2795 if (_pointer_tracking) { | |
2796 guarantee(_adjusted_pointers->contains(p), "should have seen this pointer"); | |
2797 _adjusted_pointers->remove(p); | |
2798 } | |
2799 } else { | |
2800 ptrdiff_t index = _root_refs_stack->find(p); | |
2801 if (index != -1) { | |
2802 int l = _root_refs_stack->length(); | |
2803 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
|
2804 void* last = _root_refs_stack->pop(); |
0 | 2805 assert(last != p, "should be different"); |
2806 _root_refs_stack->at_put(index, last); | |
2807 } else { | |
2808 _root_refs_stack->remove(p); | |
2809 } | |
2810 } | |
2811 } | |
2812 } | |
2813 | |
2814 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
2815 void PSParallelCompact::check_adjust_pointer(void* p) { |
0 | 2816 _adjusted_pointers->push(p); |
2817 } | |
2818 | |
2819 | |
2820 class AdjusterTracker: public OopClosure { | |
2821 public: | |
2822 AdjusterTracker() {}; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
79
diff
changeset
|
2823 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
|
2824 void do_oop(narrowOop* o) { PSParallelCompact::check_adjust_pointer(o); } |
0 | 2825 }; |
2826 | |
2827 | |
2828 void PSParallelCompact::track_interior_pointers(oop obj) { | |
2829 if (ValidateMarkSweep) { | |
2830 _adjusted_pointers->clear(); | |
2831 _pointer_tracking = true; | |
2832 | |
2833 AdjusterTracker checker; | |
2834 obj->oop_iterate(&checker); | |
2835 } | |
2836 } | |
2837 | |
2838 | |
2839 void PSParallelCompact::check_interior_pointers() { | |
2840 if (ValidateMarkSweep) { | |
2841 _pointer_tracking = false; | |
2842 guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers"); | |
2843 } | |
2844 } | |
2845 | |
2846 | |
2847 void PSParallelCompact::reset_live_oop_tracking(bool at_perm) { | |
2848 if (ValidateMarkSweep) { | |
2849 guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops"); | |
2850 _live_oops_index = at_perm ? _live_oops_index_at_perm : 0; | |
2851 } | |
2852 } | |
2853 | |
2854 | |
2855 void PSParallelCompact::register_live_oop(oop p, size_t size) { | |
2856 if (ValidateMarkSweep) { | |
2857 _live_oops->push(p); | |
2858 _live_oops_size->push(size); | |
2859 _live_oops_index++; | |
2860 } | |
2861 } | |
2862 | |
2863 void PSParallelCompact::validate_live_oop(oop p, size_t size) { | |
2864 if (ValidateMarkSweep) { | |
2865 oop obj = _live_oops->at((int)_live_oops_index); | |
2866 guarantee(obj == p, "should be the same object"); | |
2867 guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size"); | |
2868 _live_oops_index++; | |
2869 } | |
2870 } | |
2871 | |
2872 void PSParallelCompact::live_oop_moved_to(HeapWord* q, size_t size, | |
2873 HeapWord* compaction_top) { | |
2874 assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top), | |
2875 "should be moved to forwarded location"); | |
2876 if (ValidateMarkSweep) { | |
2877 PSParallelCompact::validate_live_oop(oop(q), size); | |
2878 _live_oops_moved_to->push(oop(compaction_top)); | |
2879 } | |
2880 if (RecordMarkSweepCompaction) { | |
2881 _cur_gc_live_oops->push(q); | |
2882 _cur_gc_live_oops_moved_to->push(compaction_top); | |
2883 _cur_gc_live_oops_size->push(size); | |
2884 } | |
2885 } | |
2886 | |
2887 | |
2888 void PSParallelCompact::compaction_complete() { | |
2889 if (RecordMarkSweepCompaction) { | |
2890 GrowableArray<HeapWord*>* _tmp_live_oops = _cur_gc_live_oops; | |
2891 GrowableArray<HeapWord*>* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to; | |
2892 GrowableArray<size_t> * _tmp_live_oops_size = _cur_gc_live_oops_size; | |
2893 | |
2894 _cur_gc_live_oops = _last_gc_live_oops; | |
2895 _cur_gc_live_oops_moved_to = _last_gc_live_oops_moved_to; | |
2896 _cur_gc_live_oops_size = _last_gc_live_oops_size; | |
2897 _last_gc_live_oops = _tmp_live_oops; | |
2898 _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to; | |
2899 _last_gc_live_oops_size = _tmp_live_oops_size; | |
2900 } | |
2901 } | |
2902 | |
2903 | |
2904 void PSParallelCompact::print_new_location_of_heap_address(HeapWord* q) { | |
2905 if (!RecordMarkSweepCompaction) { | |
2906 tty->print_cr("Requires RecordMarkSweepCompaction to be enabled"); | |
2907 return; | |
2908 } | |
2909 | |
2910 if (_last_gc_live_oops == NULL) { | |
2911 tty->print_cr("No compaction information gathered yet"); | |
2912 return; | |
2913 } | |
2914 | |
2915 for (int i = 0; i < _last_gc_live_oops->length(); i++) { | |
2916 HeapWord* old_oop = _last_gc_live_oops->at(i); | |
2917 size_t sz = _last_gc_live_oops_size->at(i); | |
2918 if (old_oop <= q && q < (old_oop + sz)) { | |
2919 HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i); | |
2920 size_t offset = (q - old_oop); | |
2921 tty->print_cr("Address " PTR_FORMAT, q); | |
2922 tty->print_cr(" Was in oop " PTR_FORMAT ", size %d, at offset %d", old_oop, sz, offset); | |
2923 tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset); | |
2924 return; | |
2925 } | |
2926 } | |
2927 | |
2928 tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q); | |
2929 } | |
2930 #endif //VALIDATE_MARK_SWEEP | |
2931 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2932 // Update interior oops in the ranges of regions [beg_region, end_region). |
0 | 2933 void |
2934 PSParallelCompact::update_and_deadwood_in_dense_prefix(ParCompactionManager* cm, | |
2935 SpaceId space_id, | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2936 size_t beg_region, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2937 size_t end_region) { |
0 | 2938 ParallelCompactData& sd = summary_data(); |
2939 ParMarkBitMap* const mbm = mark_bitmap(); | |
2940 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2941 HeapWord* beg_addr = sd.region_to_addr(beg_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2942 HeapWord* const end_addr = sd.region_to_addr(end_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2943 assert(beg_region <= end_region, "bad region range"); |
0 | 2944 assert(end_addr <= dense_prefix(space_id), "not in the dense prefix"); |
2945 | |
2946 #ifdef ASSERT | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2947 // Claim the regions to avoid triggering an assert when they are marked as |
0 | 2948 // filled. |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2949 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
|
2950 assert(sd.region(claim_region)->claim_unsafe(), "claim() failed"); |
0 | 2951 } |
2952 #endif // #ifdef ASSERT | |
2953 | |
2954 if (beg_addr != space(space_id)->bottom()) { | |
2955 // 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
|
2956 // 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
|
2957 // 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
|
2958 // 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
|
2959 // 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
|
2960 // 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
|
2961 // space. |
0 | 2962 assert(beg_addr > space(space_id)->bottom(), "sanity"); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2963 const RegionData* const cp = sd.region(beg_region); |
0 | 2964 if (cp->partial_obj_size() != 0) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2965 beg_addr = sd.partial_obj_end(beg_region); |
0 | 2966 } else if (dead_space_crosses_boundary(cp, mbm->addr_to_bit(beg_addr))) { |
2967 beg_addr = mbm->find_obj_beg(beg_addr, end_addr); | |
2968 } | |
2969 } | |
2970 | |
2971 if (beg_addr < end_addr) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2972 // A live object or block of dead space starts in this range of Regions. |
0 | 2973 HeapWord* const dense_prefix_end = dense_prefix(space_id); |
2974 | |
2975 // Create closures and iterate. | |
2976 UpdateOnlyClosure update_closure(mbm, cm, space_id); | |
2977 FillClosure fill_closure(cm, space_id); | |
2978 ParMarkBitMap::IterationStatus status; | |
2979 status = mbm->iterate(&update_closure, &fill_closure, beg_addr, end_addr, | |
2980 dense_prefix_end); | |
2981 if (status == ParMarkBitMap::incomplete) { | |
2982 update_closure.do_addr(update_closure.source()); | |
2983 } | |
2984 } | |
2985 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2986 // Mark the regions as filled. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2987 RegionData* const beg_cp = sd.region(beg_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2988 RegionData* const end_cp = sd.region(end_region); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
2989 for (RegionData* cp = beg_cp; cp < end_cp; ++cp) { |
0 | 2990 cp->set_completed(); |
2991 } | |
2992 } | |
2993 | |
2994 // Return the SpaceId for the space containing addr. If addr is not in the | |
2995 // heap, last_space_id is returned. In debug mode it expects the address to be | |
2996 // in the heap and asserts such. | |
2997 PSParallelCompact::SpaceId PSParallelCompact::space_id(HeapWord* addr) { | |
2998 assert(Universe::heap()->is_in_reserved(addr), "addr not in the heap"); | |
2999 | |
3000 for (unsigned int id = perm_space_id; id < last_space_id; ++id) { | |
3001 if (_space_info[id].space()->contains(addr)) { | |
3002 return SpaceId(id); | |
3003 } | |
3004 } | |
3005 | |
3006 assert(false, "no space contains the addr"); | |
3007 return last_space_id; | |
3008 } | |
3009 | |
3010 void PSParallelCompact::update_deferred_objects(ParCompactionManager* cm, | |
3011 SpaceId id) { | |
3012 assert(id < last_space_id, "bad space id"); | |
3013 | |
3014 ParallelCompactData& sd = summary_data(); | |
3015 const SpaceInfo* const space_info = _space_info + id; | |
3016 ObjectStartArray* const start_array = space_info->start_array(); | |
3017 | |
3018 const MutableSpace* const space = space_info->space(); | |
3019 assert(space_info->dense_prefix() >= space->bottom(), "dense_prefix not set"); | |
3020 HeapWord* const beg_addr = space_info->dense_prefix(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3021 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
|
3022 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3023 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
|
3024 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
|
3025 const RegionData* cur_region; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3026 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
|
3027 HeapWord* const addr = cur_region->deferred_obj_addr(); |
0 | 3028 if (addr != NULL) { |
3029 if (start_array != NULL) { | |
3030 start_array->allocate_block(addr); | |
3031 } | |
3032 oop(addr)->update_contents(cm); | |
3033 assert(oop(addr)->is_oop_or_null(), "should be an oop now"); | |
3034 } | |
3035 } | |
3036 } | |
3037 | |
3038 // Skip over count live words starting from beg, and return the address of the | |
3039 // next live word. Unless marked, the word corresponding to beg is assumed to | |
3040 // be dead. Callers must either ensure beg does not correspond to the middle of | |
3041 // an object, or account for those live words in some other way. Callers must | |
3042 // also ensure that there are enough live words in the range [beg, end) to skip. | |
3043 HeapWord* | |
3044 PSParallelCompact::skip_live_words(HeapWord* beg, HeapWord* end, size_t count) | |
3045 { | |
3046 assert(count > 0, "sanity"); | |
3047 | |
3048 ParMarkBitMap* m = mark_bitmap(); | |
3049 idx_t bits_to_skip = m->words_to_bits(count); | |
3050 idx_t cur_beg = m->addr_to_bit(beg); | |
3051 const idx_t search_end = BitMap::word_align_up(m->addr_to_bit(end)); | |
3052 | |
3053 do { | |
3054 cur_beg = m->find_obj_beg(cur_beg, search_end); | |
3055 idx_t cur_end = m->find_obj_end(cur_beg, search_end); | |
3056 const size_t obj_bits = cur_end - cur_beg + 1; | |
3057 if (obj_bits > bits_to_skip) { | |
3058 return m->bit_to_addr(cur_beg + bits_to_skip); | |
3059 } | |
3060 bits_to_skip -= obj_bits; | |
3061 cur_beg = cur_end + 1; | |
3062 } while (bits_to_skip > 0); | |
3063 | |
3064 // Skipping the desired number of words landed just past the end of an object. | |
3065 // Find the start of the next object. | |
3066 cur_beg = m->find_obj_beg(cur_beg, search_end); | |
3067 assert(cur_beg < m->addr_to_bit(end), "not enough live words to skip"); | |
3068 return m->bit_to_addr(cur_beg); | |
3069 } | |
3070 | |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3071 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
|
3072 SpaceId src_space_id, |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3073 size_t src_region_idx) |
0 | 3074 { |
482
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3075 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
|
3076 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3077 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
|
3078 if (split_info.dest_region_addr() == dest_addr) { |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3079 // 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
|
3080 // be copied to dest_addr. |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3081 return split_info.first_src_addr(); |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3082 } |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3083 |
7c2386d67889
6765745: par compact - allow young gen spaces to be split
jcoomes
parents:
481
diff
changeset
|
3084 const ParallelCompactData& sd = summary_data(); |
0 | 3085 ParMarkBitMap* const bitmap = mark_bitmap(); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3086 const size_t RegionSize = ParallelCompactData::RegionSize; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3087 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3088 assert(sd.is_region_aligned(dest_addr), "not aligned"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3089 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
|
3090 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
|
3091 HeapWord* const src_region_destination = src_region_ptr->destination(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3092 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3093 assert(dest_addr >= src_region_destination, "wrong src region"); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3094 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
|
3095 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3096 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
|
3097 HeapWord* const src_region_end = src_region_beg + RegionSize; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3098 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3099 HeapWord* addr = src_region_beg; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3100 if (dest_addr == src_region_destination) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3101 // Return the first live word in the source region. |
0 | 3102 if (partial_obj_size == 0) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3103 addr = bitmap->find_obj_beg(addr, src_region_end); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3104 assert(addr < src_region_end, "no objects start in src region"); |
0 | 3105 } |
3106 return addr; | |
3107 } | |
3108 | |
3109 // Must skip some live data. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3110 size_t words_to_skip = dest_addr - src_region_destination; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3111 assert(src_region_ptr->data_size() > words_to_skip, "wrong src region"); |
0 | 3112 |
3113 if (partial_obj_size >= words_to_skip) { | |
3114 // All the live words to skip are part of the partial object. | |
3115 addr += words_to_skip; | |
3116 if (partial_obj_size == words_to_skip) { | |
3117 // Find the first live word past the partial object. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3118 addr = bitmap->find_obj_beg(addr, src_region_end); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3119 assert(addr < src_region_end, "wrong src region"); |
0 | 3120 } |
3121 return addr; | |
3122 } | |
3123 | |
3124 // Skip over the partial object (if any). | |
3125 if (partial_obj_size != 0) { | |
3126 words_to_skip -= partial_obj_size; | |
3127 addr += partial_obj_size; | |
3128 } | |
3129 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3130 // 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
|
3131 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
|
3132 assert(addr < src_region_end, "wrong src region"); |
0 | 3133 return addr; |
3134 } | |
3135 | |
3136 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
|
3137 SpaceId src_space_id, |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3138 size_t beg_region, |
0 | 3139 HeapWord* end_addr) |
3140 { | |
3141 ParallelCompactData& sd = summary_data(); | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3142 |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3143 #ifdef ASSERT |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3144 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
|
3145 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
|
3146 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
|
3147 "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
|
3148 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
|
3149 "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
|
3150 #endif // #ifdef ASSERT |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3151 |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3152 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
|
3153 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
|
3154 |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3155 // 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
|
3156 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
|
3157 RegionData* const enqueue_end = |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3158 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
|
3159 |
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3160 for (RegionData* cur = beg; cur < end; ++cur) { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3161 assert(cur->data_size() > 0, "region must have live data"); |
0 | 3162 cur->decrement_destination_count(); |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3163 if (cur < enqueue_end && cur->available() && cur->claim()) { |
1638 | 3164 cm->push_region(sd.region(cur)); |
0 | 3165 } |
3166 } | |
3167 } | |
3168 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3169 size_t PSParallelCompact::next_src_region(MoveAndUpdateClosure& closure, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3170 SpaceId& src_space_id, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3171 HeapWord*& src_space_top, |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3172 HeapWord* end_addr) |
0 | 3173 { |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3174 typedef ParallelCompactData::RegionData RegionData; |
0 | 3175 |
3176 ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3177 const size_t region_size = ParallelCompactData::RegionSize; |
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 size_t src_region_idx = 0; |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3180 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3181 // 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
|
3182 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
|
3183 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
|
3184 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
|
3185 const RegionData* const top_region_ptr = |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3186 sd.addr_to_region_ptr(top_aligned_up); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3187 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
|
3188 ++src_region_ptr; |
0 | 3189 } |
3190 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3191 if (src_region_ptr < top_region_ptr) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3192 // 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
|
3193 // and the source address to match src_region_ptr. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3194 src_region_idx = sd.region(src_region_ptr); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3195 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
|
3196 if (src_region_addr > closure.source()) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3197 closure.set_source(src_region_addr); |
0 | 3198 } |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3199 return src_region_idx; |
0 | 3200 } |
3201 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3202 // Switch to a new source space and find the first non-empty region. |
0 | 3203 unsigned int space_id = src_space_id + 1; |
3204 assert(space_id < last_space_id, "not enough spaces"); | |
3205 | |
3206 HeapWord* const destination = closure.destination(); | |
3207 | |
3208 do { | |
3209 MutableSpace* space = _space_info[space_id].space(); | |
3210 HeapWord* const bottom = space->bottom(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3211 const RegionData* const bottom_cp = sd.addr_to_region_ptr(bottom); |
0 | 3212 |
3213 // Iterate over the spaces that do not compact into themselves. | |
3214 if (bottom_cp->destination() != bottom) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3215 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
|
3216 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
|
3217 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3218 for (const RegionData* src_cp = bottom_cp; src_cp < top_cp; ++src_cp) { |
0 | 3219 if (src_cp->live_obj_size() > 0) { |
3220 // Found it. | |
3221 assert(src_cp->destination() == destination, | |
3222 "first live obj in the space must match the destination"); | |
3223 assert(src_cp->partial_obj_size() == 0, | |
3224 "a space cannot begin with a partial obj"); | |
3225 | |
3226 src_space_id = SpaceId(space_id); | |
3227 src_space_top = space->top(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3228 const size_t src_region_idx = sd.region(src_cp); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3229 closure.set_source(sd.region_to_addr(src_region_idx)); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3230 return src_region_idx; |
0 | 3231 } else { |
3232 assert(src_cp->data_size() == 0, "sanity"); | |
3233 } | |
3234 } | |
3235 } | |
3236 } while (++space_id < last_space_id); | |
3237 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3238 assert(false, "no source region was found"); |
0 | 3239 return 0; |
3240 } | |
3241 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3242 void PSParallelCompact::fill_region(ParCompactionManager* cm, size_t region_idx) |
0 | 3243 { |
3244 typedef ParMarkBitMap::IterationStatus IterationStatus; | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3245 const size_t RegionSize = ParallelCompactData::RegionSize; |
0 | 3246 ParMarkBitMap* const bitmap = mark_bitmap(); |
3247 ParallelCompactData& sd = summary_data(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3248 RegionData* const region_ptr = sd.region(region_idx); |
0 | 3249 |
3250 // Get the items needed to construct the closure. | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3251 HeapWord* dest_addr = sd.region_to_addr(region_idx); |
0 | 3252 SpaceId dest_space_id = space_id(dest_addr); |
3253 ObjectStartArray* start_array = _space_info[dest_space_id].start_array(); | |
3254 HeapWord* new_top = _space_info[dest_space_id].new_top(); | |
3255 assert(dest_addr < new_top, "sanity"); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3256 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
|
3257 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3258 // Get the source region and related info. |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3259 size_t src_region_idx = region_ptr->source_region(); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3260 SpaceId src_space_id = space_id(sd.region_to_addr(src_region_idx)); |
0 | 3261 HeapWord* src_space_top = _space_info[src_space_id].space()->top(); |
3262 | |
3263 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
|
3264 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
|
3265 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3266 // 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
|
3267 // 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
|
3268 if (src_region_idx == region_idx) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3269 src_region_idx += 1; |
0 | 3270 } |
3271 | |
3272 if (bitmap->is_unmarked(closure.source())) { | |
3273 // The first source word is in the middle of an object; copy the remainder | |
3274 // of the object or as much as will fit. The fact that pointer updates were | |
3275 // deferred will be noted when the object header is processed. | |
3276 HeapWord* const old_src_addr = closure.source(); | |
3277 closure.copy_partial_obj(); | |
3278 if (closure.is_full()) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3279 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
|
3280 closure.source()); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3281 region_ptr->set_deferred_obj_addr(NULL); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3282 region_ptr->set_completed(); |
0 | 3283 return; |
3284 } | |
3285 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3286 HeapWord* const end_addr = sd.region_align_down(closure.source()); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3287 if (sd.region_align_down(old_src_addr) != end_addr) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3288 // 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
|
3289 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
|
3290 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3291 // Move to the next source region, possibly switching spaces as well. All |
0 | 3292 // args except end_addr may be modified. |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3293 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
|
3294 end_addr); |
0 | 3295 } |
3296 } | |
3297 | |
3298 do { | |
3299 HeapWord* const cur_addr = closure.source(); | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3300 HeapWord* const end_addr = MIN2(sd.region_align_up(cur_addr + 1), |
0 | 3301 src_space_top); |
3302 IterationStatus status = bitmap->iterate(&closure, cur_addr, end_addr); | |
3303 | |
3304 if (status == ParMarkBitMap::incomplete) { | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3305 // 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
|
3306 // region. |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
1387
diff
changeset
|
3307 assert(closure.source() < end_addr, "sanity"); |
0 | 3308 HeapWord* const obj_beg = closure.source(); |
3309 HeapWord* const range_end = MIN2(obj_beg + closure.words_remaining(), | |
3310 src_space_top); | |
3311 HeapWord* const obj_end = bitmap->find_obj_end(obj_beg, range_end); | |
3312 if (obj_end < range_end) { | |
3313 // The end was found; the entire object will fit. | |
3314 status = closure.do_addr(obj_beg, bitmap->obj_size(obj_beg, obj_end)); | |
3315 assert(status != ParMarkBitMap::would_overflow, "sanity"); | |
3316 } else { | |
3317 // The end was not found; the object will not fit. | |
3318 assert(range_end < src_space_top, "obj cannot cross space boundary"); | |
3319 status = ParMarkBitMap::would_overflow; | |
3320 } | |
3321 } | |
3322 | |
3323 if (status == ParMarkBitMap::would_overflow) { | |
3324 // 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
|
3325 // 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
|
3326 region_ptr->set_deferred_obj_addr(closure.destination()); |
0 | 3327 status = closure.copy_until_full(); // copies from closure.source() |
3328 | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3329 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
|
3330 closure.source()); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3331 region_ptr->set_completed(); |
0 | 3332 return; |
3333 } | |
3334 | |
3335 if (status == ParMarkBitMap::full) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3336 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
|
3337 closure.source()); |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3338 region_ptr->set_deferred_obj_addr(NULL); |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3339 region_ptr->set_completed(); |
0 | 3340 return; |
3341 } | |
3342 | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3343 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
|
3344 |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3345 // Move to the next source region, possibly switching spaces as well. All |
0 | 3346 // args except end_addr may be modified. |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3347 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
|
3348 end_addr); |
0 | 3349 } while (true); |
3350 } | |
3351 | |
3352 void | |
3353 PSParallelCompact::move_and_update(ParCompactionManager* cm, SpaceId space_id) { | |
3354 const MutableSpace* sp = space(space_id); | |
3355 if (sp->is_empty()) { | |
3356 return; | |
3357 } | |
3358 | |
3359 ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
3360 ParMarkBitMap* const bitmap = mark_bitmap(); | |
3361 HeapWord* const dp_addr = dense_prefix(space_id); | |
3362 HeapWord* beg_addr = sp->bottom(); | |
3363 HeapWord* end_addr = sp->top(); | |
3364 | |
3365 #ifdef ASSERT | |
3366 assert(beg_addr <= dp_addr && dp_addr <= end_addr, "bad dense prefix"); | |
3367 if (cm->should_verify_only()) { | |
3368 VerifyUpdateClosure verify_update(cm, sp); | |
3369 bitmap->iterate(&verify_update, beg_addr, end_addr); | |
3370 return; | |
3371 } | |
3372 | |
3373 if (cm->should_reset_only()) { | |
3374 ResetObjectsClosure reset_objects(cm); | |
3375 bitmap->iterate(&reset_objects, beg_addr, end_addr); | |
3376 return; | |
3377 } | |
3378 #endif | |
3379 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3380 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
|
3381 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
|
3382 if (beg_region < dp_region) { |
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3383 update_and_deadwood_in_dense_prefix(cm, space_id, beg_region, dp_region); |
0 | 3384 } |
3385 | |
375
81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
jcoomes
parents:
374
diff
changeset
|
3386 // 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
|
3387 // 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
|
3388 HeapWord* const dest_addr = sd.partial_obj_end(dp_region); |
0 | 3389 HeapWord* const new_top = _space_info[space_id].new_top(); |
3390 assert(new_top >= dest_addr, "bad new_top value"); | |
3391 const size_t words = pointer_delta(new_top, dest_addr); | |
3392 | |
3393 if (words > 0) { | |
3394 ObjectStartArray* start_array = _space_info[space_id].start_array(); | |
3395 MoveAndUpdateClosure closure(bitmap, cm, start_array, dest_addr, words); | |
3396 | |
3397 ParMarkBitMap::IterationStatus status; | |
3398 status = bitmap->iterate(&closure, dest_addr, end_addr); | |
3399 assert(status == ParMarkBitMap::full, "iteration not complete"); | |
3400 assert(bitmap->find_obj_beg(closure.source(), end_addr) == end_addr, | |
3401 "live objects skipped because closure is full"); | |
3402 } | |
3403 } | |
3404 | |
3405 jlong PSParallelCompact::millis_since_last_gc() { | |
3406 jlong ret_val = os::javaTimeMillis() - _time_of_last_gc; | |
3407 // XXX See note in genCollectedHeap::millis_since_last_gc(). | |
3408 if (ret_val < 0) { | |
3409 NOT_PRODUCT(warning("time warp: %d", ret_val);) | |
3410 return 0; | |
3411 } | |
3412 return ret_val; | |
3413 } | |
3414 | |
3415 void PSParallelCompact::reset_millis_since_last_gc() { | |
3416 _time_of_last_gc = os::javaTimeMillis(); | |
3417 } | |
3418 | |
3419 ParMarkBitMap::IterationStatus MoveAndUpdateClosure::copy_until_full() | |
3420 { | |
3421 if (source() != destination()) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3422 DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());) |
0 | 3423 Copy::aligned_conjoint_words(source(), destination(), words_remaining()); |
3424 } | |
3425 update_state(words_remaining()); | |
3426 assert(is_full(), "sanity"); | |
3427 return ParMarkBitMap::full; | |
3428 } | |
3429 | |
3430 void MoveAndUpdateClosure::copy_partial_obj() | |
3431 { | |
3432 size_t words = words_remaining(); | |
3433 | |
3434 HeapWord* const range_end = MIN2(source() + words, bitmap()->region_end()); | |
3435 HeapWord* const end_addr = bitmap()->find_obj_end(source(), range_end); | |
3436 if (end_addr < range_end) { | |
3437 words = bitmap()->obj_size(source(), end_addr); | |
3438 } | |
3439 | |
3440 // This test is necessary; if omitted, the pointer updates to a partial object | |
3441 // that crosses the dense prefix boundary could be overwritten. | |
3442 if (source() != destination()) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3443 DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());) |
0 | 3444 Copy::aligned_conjoint_words(source(), destination(), words); |
3445 } | |
3446 update_state(words); | |
3447 } | |
3448 | |
3449 ParMarkBitMapClosure::IterationStatus | |
3450 MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) { | |
3451 assert(destination() != NULL, "sanity"); | |
3452 assert(bitmap()->obj_size(addr) == words, "bad size"); | |
3453 | |
3454 _source = addr; | |
3455 assert(PSParallelCompact::summary_data().calc_new_pointer(source()) == | |
3456 destination(), "wrong destination"); | |
3457 | |
3458 if (words > words_remaining()) { | |
3459 return ParMarkBitMap::would_overflow; | |
3460 } | |
3461 | |
3462 // The start_array must be updated even if the object is not moving. | |
3463 if (_start_array != NULL) { | |
3464 _start_array->allocate_block(destination()); | |
3465 } | |
3466 | |
3467 if (destination() != source()) { | |
495
234c22e54b98
6784849: par compact - can fail when to_space is non-empty
jcoomes
parents:
483
diff
changeset
|
3468 DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());) |
0 | 3469 Copy::aligned_conjoint_words(source(), destination(), words); |
3470 } | |
3471 | |
3472 oop moved_oop = (oop) destination(); | |
3473 moved_oop->update_contents(compaction_manager()); | |
3474 assert(moved_oop->is_oop_or_null(), "Object should be whole at this point"); | |
3475 | |
3476 update_state(words); | |
3477 assert(destination() == (HeapWord*)moved_oop + moved_oop->size(), "sanity"); | |
3478 return is_full() ? ParMarkBitMap::full : ParMarkBitMap::incomplete; | |
3479 } | |
3480 | |
3481 UpdateOnlyClosure::UpdateOnlyClosure(ParMarkBitMap* mbm, | |
3482 ParCompactionManager* cm, | |
3483 PSParallelCompact::SpaceId space_id) : | |
3484 ParMarkBitMapClosure(mbm, cm), | |
3485 _space_id(space_id), | |
3486 _start_array(PSParallelCompact::start_array(space_id)) | |
3487 { | |
3488 } | |
3489 | |
3490 // Updates the references in the object to their new values. | |
3491 ParMarkBitMapClosure::IterationStatus | |
3492 UpdateOnlyClosure::do_addr(HeapWord* addr, size_t words) { | |
3493 do_addr(addr); | |
3494 return ParMarkBitMap::incomplete; | |
3495 } | |
3496 | |
3497 // Verify the new location using the forwarding pointer | |
3498 // from MarkSweep::mark_sweep_phase2(). Set the mark_word | |
3499 // to the initial value. | |
3500 ParMarkBitMapClosure::IterationStatus | |
3501 PSParallelCompact::VerifyUpdateClosure::do_addr(HeapWord* addr, size_t words) { | |
3502 // The second arg (words) is not used. | |
3503 oop obj = (oop) addr; | |
3504 HeapWord* forwarding_ptr = (HeapWord*) obj->mark()->decode_pointer(); | |
3505 HeapWord* new_pointer = summary_data().calc_new_pointer(obj); | |
3506 if (forwarding_ptr == NULL) { | |
3507 // The object is dead or not moving. | |
3508 assert(bitmap()->is_unmarked(obj) || (new_pointer == (HeapWord*) obj), | |
3509 "Object liveness is wrong."); | |
3510 return ParMarkBitMap::incomplete; | |
3511 } | |
3251
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
3512 assert(HeapMaximumCompactionInterval > 1 || MarkSweepAlwaysCompactCount > 1 || |
eda9eb483d29
6841742: par compact - remove unused/unsupported options
jcoomes
parents:
2369
diff
changeset
|
3513 forwarding_ptr == new_pointer, "new location is incorrect"); |
0 | 3514 return ParMarkBitMap::incomplete; |
3515 } | |
3516 | |
3517 // Reset objects modified for debug checking. | |
3518 ParMarkBitMapClosure::IterationStatus | |
3519 PSParallelCompact::ResetObjectsClosure::do_addr(HeapWord* addr, size_t words) { | |
3520 // The second arg (words) is not used. | |
3521 oop obj = (oop) addr; | |
3522 obj->init_mark(); | |
3523 return ParMarkBitMap::incomplete; | |
3524 } | |
3525 | |
3526 // Prepare for compaction. This method is executed once | |
3527 // (i.e., by a single thread) before compaction. | |
3528 // Save the updated location of the intArrayKlassObj for | |
3529 // filling holes in the dense prefix. | |
3530 void PSParallelCompact::compact_prologue() { | |
3531 _updated_int_array_klass_obj = (klassOop) | |
3532 summary_data().calc_new_pointer(Universe::intArrayKlassObj()); | |
3533 } | |
3534 |