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