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