Mercurial > hg > graal-jvmci-8
comparison src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp @ 375:81cd571500b0
6725697: par compact - rename class ChunkData to RegionData
Reviewed-by: iveresov, tonyp
author | jcoomes |
---|---|
date | Tue, 30 Sep 2008 12:20:22 -0700 |
parents | 850fdf70db2b |
children | 0166ac265d53 |
comparison
equal
deleted
inserted
replaced
374:a4b729f5b611 | 375:81cd571500b0 |
---|---|
74 | 74 |
75 class ParallelCompactData | 75 class ParallelCompactData |
76 { | 76 { |
77 public: | 77 public: |
78 // Sizes are in HeapWords, unless indicated otherwise. | 78 // Sizes are in HeapWords, unless indicated otherwise. |
79 static const size_t Log2ChunkSize; | 79 static const size_t Log2RegionSize; |
80 static const size_t ChunkSize; | 80 static const size_t RegionSize; |
81 static const size_t ChunkSizeBytes; | 81 static const size_t RegionSizeBytes; |
82 | 82 |
83 // Mask for the bits in a size_t to get an offset within a chunk. | 83 // Mask for the bits in a size_t to get an offset within a region. |
84 static const size_t ChunkSizeOffsetMask; | 84 static const size_t RegionSizeOffsetMask; |
85 // Mask for the bits in a pointer to get an offset within a chunk. | 85 // Mask for the bits in a pointer to get an offset within a region. |
86 static const size_t ChunkAddrOffsetMask; | 86 static const size_t RegionAddrOffsetMask; |
87 // Mask for the bits in a pointer to get the address of the start of a chunk. | 87 // Mask for the bits in a pointer to get the address of the start of a region. |
88 static const size_t ChunkAddrMask; | 88 static const size_t RegionAddrMask; |
89 | 89 |
90 static const size_t Log2BlockSize; | 90 static const size_t Log2BlockSize; |
91 static const size_t BlockSize; | 91 static const size_t BlockSize; |
92 static const size_t BlockOffsetMask; | 92 static const size_t BlockOffsetMask; |
93 static const size_t BlockMask; | 93 static const size_t BlockMask; |
94 | 94 |
95 static const size_t BlocksPerChunk; | 95 static const size_t BlocksPerRegion; |
96 | 96 |
97 class ChunkData | 97 class RegionData |
98 { | 98 { |
99 public: | 99 public: |
100 // Destination address of the chunk. | 100 // Destination address of the region. |
101 HeapWord* destination() const { return _destination; } | 101 HeapWord* destination() const { return _destination; } |
102 | 102 |
103 // The first chunk containing data destined for this chunk. | 103 // The first region containing data destined for this region. |
104 size_t source_chunk() const { return _source_chunk; } | 104 size_t source_region() const { return _source_region; } |
105 | 105 |
106 // The object (if any) starting in this chunk and ending in a different | 106 // The object (if any) starting in this region and ending in a different |
107 // chunk that could not be updated during the main (parallel) compaction | 107 // region that could not be updated during the main (parallel) compaction |
108 // phase. This is different from _partial_obj_addr, which is an object that | 108 // phase. This is different from _partial_obj_addr, which is an object that |
109 // extends onto a source chunk. However, the two uses do not overlap in | 109 // extends onto a source region. However, the two uses do not overlap in |
110 // time, so the same field is used to save space. | 110 // time, so the same field is used to save space. |
111 HeapWord* deferred_obj_addr() const { return _partial_obj_addr; } | 111 HeapWord* deferred_obj_addr() const { return _partial_obj_addr; } |
112 | 112 |
113 // The starting address of the partial object extending onto the chunk. | 113 // The starting address of the partial object extending onto the region. |
114 HeapWord* partial_obj_addr() const { return _partial_obj_addr; } | 114 HeapWord* partial_obj_addr() const { return _partial_obj_addr; } |
115 | 115 |
116 // Size of the partial object extending onto the chunk (words). | 116 // Size of the partial object extending onto the region (words). |
117 size_t partial_obj_size() const { return _partial_obj_size; } | 117 size_t partial_obj_size() const { return _partial_obj_size; } |
118 | 118 |
119 // Size of live data that lies within this chunk due to objects that start | 119 // Size of live data that lies within this region due to objects that start |
120 // in this chunk (words). This does not include the partial object | 120 // in this region (words). This does not include the partial object |
121 // extending onto the chunk (if any), or the part of an object that extends | 121 // extending onto the region (if any), or the part of an object that extends |
122 // onto the next chunk (if any). | 122 // onto the next region (if any). |
123 size_t live_obj_size() const { return _dc_and_los & los_mask; } | 123 size_t live_obj_size() const { return _dc_and_los & los_mask; } |
124 | 124 |
125 // Total live data that lies within the chunk (words). | 125 // Total live data that lies within the region (words). |
126 size_t data_size() const { return partial_obj_size() + live_obj_size(); } | 126 size_t data_size() const { return partial_obj_size() + live_obj_size(); } |
127 | 127 |
128 // The destination_count is the number of other chunks to which data from | 128 // The destination_count is the number of other regions to which data from |
129 // this chunk will be copied. At the end of the summary phase, the valid | 129 // this region will be copied. At the end of the summary phase, the valid |
130 // values of destination_count are | 130 // values of destination_count are |
131 // | 131 // |
132 // 0 - data from the chunk will be compacted completely into itself, or the | 132 // 0 - data from the region will be compacted completely into itself, or the |
133 // chunk is empty. The chunk can be claimed and then filled. | 133 // region is empty. The region can be claimed and then filled. |
134 // 1 - data from the chunk will be compacted into 1 other chunk; some | 134 // 1 - data from the region will be compacted into 1 other region; some |
135 // data from the chunk may also be compacted into the chunk itself. | 135 // data from the region may also be compacted into the region itself. |
136 // 2 - data from the chunk will be copied to 2 other chunks. | 136 // 2 - data from the region will be copied to 2 other regions. |
137 // | 137 // |
138 // During compaction as chunks are emptied, the destination_count is | 138 // During compaction as regions are emptied, the destination_count is |
139 // decremented (atomically) and when it reaches 0, it can be claimed and | 139 // decremented (atomically) and when it reaches 0, it can be claimed and |
140 // then filled. | 140 // then filled. |
141 // | 141 // |
142 // A chunk is claimed for processing by atomically changing the | 142 // A region is claimed for processing by atomically changing the |
143 // destination_count to the claimed value (dc_claimed). After a chunk has | 143 // destination_count to the claimed value (dc_claimed). After a region has |
144 // been filled, the destination_count should be set to the completed value | 144 // been filled, the destination_count should be set to the completed value |
145 // (dc_completed). | 145 // (dc_completed). |
146 inline uint destination_count() const; | 146 inline uint destination_count() const; |
147 inline uint destination_count_raw() const; | 147 inline uint destination_count_raw() const; |
148 | 148 |
149 // The location of the java heap data that corresponds to this chunk. | 149 // The location of the java heap data that corresponds to this region. |
150 inline HeapWord* data_location() const; | 150 inline HeapWord* data_location() const; |
151 | 151 |
152 // The highest address referenced by objects in this chunk. | 152 // The highest address referenced by objects in this region. |
153 inline HeapWord* highest_ref() const; | 153 inline HeapWord* highest_ref() const; |
154 | 154 |
155 // Whether this chunk is available to be claimed, has been claimed, or has | 155 // Whether this region is available to be claimed, has been claimed, or has |
156 // been completed. | 156 // been completed. |
157 // | 157 // |
158 // Minor subtlety: claimed() returns true if the chunk is marked | 158 // Minor subtlety: claimed() returns true if the region is marked |
159 // completed(), which is desirable since a chunk must be claimed before it | 159 // completed(), which is desirable since a region must be claimed before it |
160 // can be completed. | 160 // can be completed. |
161 bool available() const { return _dc_and_los < dc_one; } | 161 bool available() const { return _dc_and_los < dc_one; } |
162 bool claimed() const { return _dc_and_los >= dc_claimed; } | 162 bool claimed() const { return _dc_and_los >= dc_claimed; } |
163 bool completed() const { return _dc_and_los >= dc_completed; } | 163 bool completed() const { return _dc_and_los >= dc_completed; } |
164 | 164 |
165 // These are not atomic. | 165 // These are not atomic. |
166 void set_destination(HeapWord* addr) { _destination = addr; } | 166 void set_destination(HeapWord* addr) { _destination = addr; } |
167 void set_source_chunk(size_t chunk) { _source_chunk = chunk; } | 167 void set_source_region(size_t region) { _source_region = region; } |
168 void set_deferred_obj_addr(HeapWord* addr) { _partial_obj_addr = addr; } | 168 void set_deferred_obj_addr(HeapWord* addr) { _partial_obj_addr = addr; } |
169 void set_partial_obj_addr(HeapWord* addr) { _partial_obj_addr = addr; } | 169 void set_partial_obj_addr(HeapWord* addr) { _partial_obj_addr = addr; } |
170 void set_partial_obj_size(size_t words) { | 170 void set_partial_obj_size(size_t words) { |
171 _partial_obj_size = (chunk_sz_t) words; | 171 _partial_obj_size = (region_sz_t) words; |
172 } | 172 } |
173 | 173 |
174 inline void set_destination_count(uint count); | 174 inline void set_destination_count(uint count); |
175 inline void set_live_obj_size(size_t words); | 175 inline void set_live_obj_size(size_t words); |
176 inline void set_data_location(HeapWord* addr); | 176 inline void set_data_location(HeapWord* addr); |
182 inline void set_highest_ref(HeapWord* addr); | 182 inline void set_highest_ref(HeapWord* addr); |
183 inline void decrement_destination_count(); | 183 inline void decrement_destination_count(); |
184 inline bool claim(); | 184 inline bool claim(); |
185 | 185 |
186 private: | 186 private: |
187 // The type used to represent object sizes within a chunk. | 187 // The type used to represent object sizes within a region. |
188 typedef uint chunk_sz_t; | 188 typedef uint region_sz_t; |
189 | 189 |
190 // Constants for manipulating the _dc_and_los field, which holds both the | 190 // Constants for manipulating the _dc_and_los field, which holds both the |
191 // destination count and live obj size. The live obj size lives at the | 191 // destination count and live obj size. The live obj size lives at the |
192 // least significant end so no masking is necessary when adding. | 192 // least significant end so no masking is necessary when adding. |
193 static const chunk_sz_t dc_shift; // Shift amount. | 193 static const region_sz_t dc_shift; // Shift amount. |
194 static const chunk_sz_t dc_mask; // Mask for destination count. | 194 static const region_sz_t dc_mask; // Mask for destination count. |
195 static const chunk_sz_t dc_one; // 1, shifted appropriately. | 195 static const region_sz_t dc_one; // 1, shifted appropriately. |
196 static const chunk_sz_t dc_claimed; // Chunk has been claimed. | 196 static const region_sz_t dc_claimed; // Region has been claimed. |
197 static const chunk_sz_t dc_completed; // Chunk has been completed. | 197 static const region_sz_t dc_completed; // Region has been completed. |
198 static const chunk_sz_t los_mask; // Mask for live obj size. | 198 static const region_sz_t los_mask; // Mask for live obj size. |
199 | 199 |
200 HeapWord* _destination; | 200 HeapWord* _destination; |
201 size_t _source_chunk; | 201 size_t _source_region; |
202 HeapWord* _partial_obj_addr; | 202 HeapWord* _partial_obj_addr; |
203 chunk_sz_t _partial_obj_size; | 203 region_sz_t _partial_obj_size; |
204 chunk_sz_t volatile _dc_and_los; | 204 region_sz_t volatile _dc_and_los; |
205 #ifdef ASSERT | 205 #ifdef ASSERT |
206 // These enable optimizations that are only partially implemented. Use | 206 // These enable optimizations that are only partially implemented. Use |
207 // debug builds to prevent the code fragments from breaking. | 207 // debug builds to prevent the code fragments from breaking. |
208 HeapWord* _data_location; | 208 HeapWord* _data_location; |
209 HeapWord* _highest_ref; | 209 HeapWord* _highest_ref; |
210 #endif // #ifdef ASSERT | 210 #endif // #ifdef ASSERT |
211 | 211 |
212 #ifdef ASSERT | 212 #ifdef ASSERT |
213 public: | 213 public: |
214 uint _pushed; // 0 until chunk is pushed onto a worker's stack | 214 uint _pushed; // 0 until region is pushed onto a worker's stack |
215 private: | 215 private: |
216 #endif | 216 #endif |
217 }; | 217 }; |
218 | 218 |
219 // 'Blocks' allow shorter sections of the bitmap to be searched. Each Block | 219 // 'Blocks' allow shorter sections of the bitmap to be searched. Each Block |
220 // holds an offset, which is the amount of live data in the Chunk to the left | 220 // holds an offset, which is the amount of live data in the Region to the left |
221 // of the first live object in the Block. This amount of live data will | 221 // of the first live object in the Block. This amount of live data will |
222 // include any object extending into the block. The first block in | 222 // include any object extending into the block. The first block in |
223 // a chunk does not include any partial object extending into the | 223 // a region does not include any partial object extending into the |
224 // the chunk. | 224 // the region. |
225 // | 225 // |
226 // The offset also encodes the | 226 // The offset also encodes the |
227 // 'parity' of the first 1 bit in the Block: a positive offset means the | 227 // 'parity' of the first 1 bit in the Block: a positive offset means the |
228 // first 1 bit marks the start of an object, a negative offset means the first | 228 // first 1 bit marks the start of an object, a negative offset means the first |
229 // 1 bit marks the end of an object. | 229 // 1 bit marks the end of an object. |
284 | 284 |
285 public: | 285 public: |
286 ParallelCompactData(); | 286 ParallelCompactData(); |
287 bool initialize(MemRegion covered_region); | 287 bool initialize(MemRegion covered_region); |
288 | 288 |
289 size_t chunk_count() const { return _chunk_count; } | 289 size_t region_count() const { return _region_count; } |
290 | 290 |
291 // Convert chunk indices to/from ChunkData pointers. | 291 // Convert region indices to/from RegionData pointers. |
292 inline ChunkData* chunk(size_t chunk_idx) const; | 292 inline RegionData* region(size_t region_idx) const; |
293 inline size_t chunk(const ChunkData* const chunk_ptr) const; | 293 inline size_t region(const RegionData* const region_ptr) const; |
294 | 294 |
295 // Returns true if the given address is contained within the chunk | 295 // Returns true if the given address is contained within the region |
296 bool chunk_contains(size_t chunk_index, HeapWord* addr); | 296 bool region_contains(size_t region_index, HeapWord* addr); |
297 | 297 |
298 size_t block_count() const { return _block_count; } | 298 size_t block_count() const { return _block_count; } |
299 inline BlockData* block(size_t n) const; | 299 inline BlockData* block(size_t n) const; |
300 | 300 |
301 // Returns true if the given block is in the given chunk. | 301 // Returns true if the given block is in the given region. |
302 static bool chunk_contains_block(size_t chunk_index, size_t block_index); | 302 static bool region_contains_block(size_t region_index, size_t block_index); |
303 | 303 |
304 void add_obj(HeapWord* addr, size_t len); | 304 void add_obj(HeapWord* addr, size_t len); |
305 void add_obj(oop p, size_t len) { add_obj((HeapWord*)p, len); } | 305 void add_obj(oop p, size_t len) { add_obj((HeapWord*)p, len); } |
306 | 306 |
307 // Fill in the chunks covering [beg, end) so that no data moves; i.e., the | 307 // Fill in the regions covering [beg, end) so that no data moves; i.e., the |
308 // destination of chunk n is simply the start of chunk n. The argument beg | 308 // destination of region n is simply the start of region n. The argument beg |
309 // must be chunk-aligned; end need not be. | 309 // must be region-aligned; end need not be. |
310 void summarize_dense_prefix(HeapWord* beg, HeapWord* end); | 310 void summarize_dense_prefix(HeapWord* beg, HeapWord* end); |
311 | 311 |
312 bool summarize(HeapWord* target_beg, HeapWord* target_end, | 312 bool summarize(HeapWord* target_beg, HeapWord* target_end, |
313 HeapWord* source_beg, HeapWord* source_end, | 313 HeapWord* source_beg, HeapWord* source_end, |
314 HeapWord** target_next, HeapWord** source_next = 0); | 314 HeapWord** target_next, HeapWord** source_next = 0); |
315 | 315 |
316 void clear(); | 316 void clear(); |
317 void clear_range(size_t beg_chunk, size_t end_chunk); | 317 void clear_range(size_t beg_region, size_t end_region); |
318 void clear_range(HeapWord* beg, HeapWord* end) { | 318 void clear_range(HeapWord* beg, HeapWord* end) { |
319 clear_range(addr_to_chunk_idx(beg), addr_to_chunk_idx(end)); | 319 clear_range(addr_to_region_idx(beg), addr_to_region_idx(end)); |
320 } | 320 } |
321 | 321 |
322 // Return the number of words between addr and the start of the chunk | 322 // Return the number of words between addr and the start of the region |
323 // containing addr. | 323 // containing addr. |
324 inline size_t chunk_offset(const HeapWord* addr) const; | 324 inline size_t region_offset(const HeapWord* addr) const; |
325 | 325 |
326 // Convert addresses to/from a chunk index or chunk pointer. | 326 // Convert addresses to/from a region index or region pointer. |
327 inline size_t addr_to_chunk_idx(const HeapWord* addr) const; | 327 inline size_t addr_to_region_idx(const HeapWord* addr) const; |
328 inline ChunkData* addr_to_chunk_ptr(const HeapWord* addr) const; | 328 inline RegionData* addr_to_region_ptr(const HeapWord* addr) const; |
329 inline HeapWord* chunk_to_addr(size_t chunk) const; | 329 inline HeapWord* region_to_addr(size_t region) const; |
330 inline HeapWord* chunk_to_addr(size_t chunk, size_t offset) const; | 330 inline HeapWord* region_to_addr(size_t region, size_t offset) const; |
331 inline HeapWord* chunk_to_addr(const ChunkData* chunk) const; | 331 inline HeapWord* region_to_addr(const RegionData* region) const; |
332 | 332 |
333 inline HeapWord* chunk_align_down(HeapWord* addr) const; | 333 inline HeapWord* region_align_down(HeapWord* addr) const; |
334 inline HeapWord* chunk_align_up(HeapWord* addr) const; | 334 inline HeapWord* region_align_up(HeapWord* addr) const; |
335 inline bool is_chunk_aligned(HeapWord* addr) const; | 335 inline bool is_region_aligned(HeapWord* addr) const; |
336 | 336 |
337 // Analogous to chunk_offset() for blocks. | 337 // Analogous to region_offset() for blocks. |
338 size_t block_offset(const HeapWord* addr) const; | 338 size_t block_offset(const HeapWord* addr) const; |
339 size_t addr_to_block_idx(const HeapWord* addr) const; | 339 size_t addr_to_block_idx(const HeapWord* addr) const; |
340 size_t addr_to_block_idx(const oop obj) const { | 340 size_t addr_to_block_idx(const oop obj) const { |
341 return addr_to_block_idx((HeapWord*) obj); | 341 return addr_to_block_idx((HeapWord*) obj); |
342 } | 342 } |
343 inline BlockData* addr_to_block_ptr(const HeapWord* addr) const; | 343 inline BlockData* addr_to_block_ptr(const HeapWord* addr) const; |
344 inline HeapWord* block_to_addr(size_t block) const; | 344 inline HeapWord* block_to_addr(size_t block) const; |
345 | 345 |
346 // Return the address one past the end of the partial object. | 346 // Return the address one past the end of the partial object. |
347 HeapWord* partial_obj_end(size_t chunk_idx) const; | 347 HeapWord* partial_obj_end(size_t region_idx) const; |
348 | 348 |
349 // Return the new location of the object p after the | 349 // Return the new location of the object p after the |
350 // the compaction. | 350 // the compaction. |
351 HeapWord* calc_new_pointer(HeapWord* addr); | 351 HeapWord* calc_new_pointer(HeapWord* addr); |
352 | 352 |
353 // Same as calc_new_pointer() using blocks. | 353 // Same as calc_new_pointer() using blocks. |
354 HeapWord* block_calc_new_pointer(HeapWord* addr); | 354 HeapWord* block_calc_new_pointer(HeapWord* addr); |
355 | 355 |
356 // Same as calc_new_pointer() using chunks. | 356 // Same as calc_new_pointer() using regions. |
357 HeapWord* chunk_calc_new_pointer(HeapWord* addr); | 357 HeapWord* region_calc_new_pointer(HeapWord* addr); |
358 | 358 |
359 HeapWord* calc_new_pointer(oop p) { | 359 HeapWord* calc_new_pointer(oop p) { |
360 return calc_new_pointer((HeapWord*) p); | 360 return calc_new_pointer((HeapWord*) p); |
361 } | 361 } |
362 | 362 |
363 // Return the updated address for the given klass | 363 // Return the updated address for the given klass |
364 klassOop calc_new_klass(klassOop); | 364 klassOop calc_new_klass(klassOop); |
365 | 365 |
366 // Given a block returns true if the partial object for the | 366 // Given a block returns true if the partial object for the |
367 // corresponding chunk ends in the block. Returns false, otherwise | 367 // corresponding region ends in the block. Returns false, otherwise |
368 // If there is no partial object, returns false. | 368 // If there is no partial object, returns false. |
369 bool partial_obj_ends_in_block(size_t block_index); | 369 bool partial_obj_ends_in_block(size_t block_index); |
370 | 370 |
371 // Returns the block index for the block | 371 // Returns the block index for the block |
372 static size_t block_idx(BlockData* block); | 372 static size_t block_idx(BlockData* block); |
376 void verify_clear(); | 376 void verify_clear(); |
377 #endif // #ifdef ASSERT | 377 #endif // #ifdef ASSERT |
378 | 378 |
379 private: | 379 private: |
380 bool initialize_block_data(size_t region_size); | 380 bool initialize_block_data(size_t region_size); |
381 bool initialize_chunk_data(size_t region_size); | 381 bool initialize_region_data(size_t region_size); |
382 PSVirtualSpace* create_vspace(size_t count, size_t element_size); | 382 PSVirtualSpace* create_vspace(size_t count, size_t element_size); |
383 | 383 |
384 private: | 384 private: |
385 HeapWord* _region_start; | 385 HeapWord* _region_start; |
386 #ifdef ASSERT | 386 #ifdef ASSERT |
387 HeapWord* _region_end; | 387 HeapWord* _region_end; |
388 #endif // #ifdef ASSERT | 388 #endif // #ifdef ASSERT |
389 | 389 |
390 PSVirtualSpace* _chunk_vspace; | 390 PSVirtualSpace* _region_vspace; |
391 ChunkData* _chunk_data; | 391 RegionData* _region_data; |
392 size_t _chunk_count; | 392 size_t _region_count; |
393 | 393 |
394 PSVirtualSpace* _block_vspace; | 394 PSVirtualSpace* _block_vspace; |
395 BlockData* _block_data; | 395 BlockData* _block_data; |
396 size_t _block_count; | 396 size_t _block_count; |
397 }; | 397 }; |
398 | 398 |
399 inline uint | 399 inline uint |
400 ParallelCompactData::ChunkData::destination_count_raw() const | 400 ParallelCompactData::RegionData::destination_count_raw() const |
401 { | 401 { |
402 return _dc_and_los & dc_mask; | 402 return _dc_and_los & dc_mask; |
403 } | 403 } |
404 | 404 |
405 inline uint | 405 inline uint |
406 ParallelCompactData::ChunkData::destination_count() const | 406 ParallelCompactData::RegionData::destination_count() const |
407 { | 407 { |
408 return destination_count_raw() >> dc_shift; | 408 return destination_count_raw() >> dc_shift; |
409 } | 409 } |
410 | 410 |
411 inline void | 411 inline void |
412 ParallelCompactData::ChunkData::set_destination_count(uint count) | 412 ParallelCompactData::RegionData::set_destination_count(uint count) |
413 { | 413 { |
414 assert(count <= (dc_completed >> dc_shift), "count too large"); | 414 assert(count <= (dc_completed >> dc_shift), "count too large"); |
415 const chunk_sz_t live_sz = (chunk_sz_t) live_obj_size(); | 415 const region_sz_t live_sz = (region_sz_t) live_obj_size(); |
416 _dc_and_los = (count << dc_shift) | live_sz; | 416 _dc_and_los = (count << dc_shift) | live_sz; |
417 } | 417 } |
418 | 418 |
419 inline void ParallelCompactData::ChunkData::set_live_obj_size(size_t words) | 419 inline void ParallelCompactData::RegionData::set_live_obj_size(size_t words) |
420 { | 420 { |
421 assert(words <= los_mask, "would overflow"); | 421 assert(words <= los_mask, "would overflow"); |
422 _dc_and_los = destination_count_raw() | (chunk_sz_t)words; | 422 _dc_and_los = destination_count_raw() | (region_sz_t)words; |
423 } | 423 } |
424 | 424 |
425 inline void ParallelCompactData::ChunkData::decrement_destination_count() | 425 inline void ParallelCompactData::RegionData::decrement_destination_count() |
426 { | 426 { |
427 assert(_dc_and_los < dc_claimed, "already claimed"); | 427 assert(_dc_and_los < dc_claimed, "already claimed"); |
428 assert(_dc_and_los >= dc_one, "count would go negative"); | 428 assert(_dc_and_los >= dc_one, "count would go negative"); |
429 Atomic::add((int)dc_mask, (volatile int*)&_dc_and_los); | 429 Atomic::add((int)dc_mask, (volatile int*)&_dc_and_los); |
430 } | 430 } |
431 | 431 |
432 inline HeapWord* ParallelCompactData::ChunkData::data_location() const | 432 inline HeapWord* ParallelCompactData::RegionData::data_location() const |
433 { | 433 { |
434 DEBUG_ONLY(return _data_location;) | 434 DEBUG_ONLY(return _data_location;) |
435 NOT_DEBUG(return NULL;) | 435 NOT_DEBUG(return NULL;) |
436 } | 436 } |
437 | 437 |
438 inline HeapWord* ParallelCompactData::ChunkData::highest_ref() const | 438 inline HeapWord* ParallelCompactData::RegionData::highest_ref() const |
439 { | 439 { |
440 DEBUG_ONLY(return _highest_ref;) | 440 DEBUG_ONLY(return _highest_ref;) |
441 NOT_DEBUG(return NULL;) | 441 NOT_DEBUG(return NULL;) |
442 } | 442 } |
443 | 443 |
444 inline void ParallelCompactData::ChunkData::set_data_location(HeapWord* addr) | 444 inline void ParallelCompactData::RegionData::set_data_location(HeapWord* addr) |
445 { | 445 { |
446 DEBUG_ONLY(_data_location = addr;) | 446 DEBUG_ONLY(_data_location = addr;) |
447 } | 447 } |
448 | 448 |
449 inline void ParallelCompactData::ChunkData::set_completed() | 449 inline void ParallelCompactData::RegionData::set_completed() |
450 { | 450 { |
451 assert(claimed(), "must be claimed first"); | 451 assert(claimed(), "must be claimed first"); |
452 _dc_and_los = dc_completed | (chunk_sz_t) live_obj_size(); | 452 _dc_and_los = dc_completed | (region_sz_t) live_obj_size(); |
453 } | 453 } |
454 | 454 |
455 // MT-unsafe claiming of a chunk. Should only be used during single threaded | 455 // MT-unsafe claiming of a region. Should only be used during single threaded |
456 // execution. | 456 // execution. |
457 inline bool ParallelCompactData::ChunkData::claim_unsafe() | 457 inline bool ParallelCompactData::RegionData::claim_unsafe() |
458 { | 458 { |
459 if (available()) { | 459 if (available()) { |
460 _dc_and_los |= dc_claimed; | 460 _dc_and_los |= dc_claimed; |
461 return true; | 461 return true; |
462 } | 462 } |
463 return false; | 463 return false; |
464 } | 464 } |
465 | 465 |
466 inline void ParallelCompactData::ChunkData::add_live_obj(size_t words) | 466 inline void ParallelCompactData::RegionData::add_live_obj(size_t words) |
467 { | 467 { |
468 assert(words <= (size_t)los_mask - live_obj_size(), "overflow"); | 468 assert(words <= (size_t)los_mask - live_obj_size(), "overflow"); |
469 Atomic::add((int) words, (volatile int*) &_dc_and_los); | 469 Atomic::add((int) words, (volatile int*) &_dc_and_los); |
470 } | 470 } |
471 | 471 |
472 inline void ParallelCompactData::ChunkData::set_highest_ref(HeapWord* addr) | 472 inline void ParallelCompactData::RegionData::set_highest_ref(HeapWord* addr) |
473 { | 473 { |
474 #ifdef ASSERT | 474 #ifdef ASSERT |
475 HeapWord* tmp = _highest_ref; | 475 HeapWord* tmp = _highest_ref; |
476 while (addr > tmp) { | 476 while (addr > tmp) { |
477 tmp = (HeapWord*)Atomic::cmpxchg_ptr(addr, &_highest_ref, tmp); | 477 tmp = (HeapWord*)Atomic::cmpxchg_ptr(addr, &_highest_ref, tmp); |
478 } | 478 } |
479 #endif // #ifdef ASSERT | 479 #endif // #ifdef ASSERT |
480 } | 480 } |
481 | 481 |
482 inline bool ParallelCompactData::ChunkData::claim() | 482 inline bool ParallelCompactData::RegionData::claim() |
483 { | 483 { |
484 const int los = (int) live_obj_size(); | 484 const int los = (int) live_obj_size(); |
485 const int old = Atomic::cmpxchg(dc_claimed | los, | 485 const int old = Atomic::cmpxchg(dc_claimed | los, |
486 (volatile int*) &_dc_and_los, los); | 486 (volatile int*) &_dc_and_los, los); |
487 return old == los; | 487 return old == los; |
488 } | 488 } |
489 | 489 |
490 inline ParallelCompactData::ChunkData* | 490 inline ParallelCompactData::RegionData* |
491 ParallelCompactData::chunk(size_t chunk_idx) const | 491 ParallelCompactData::region(size_t region_idx) const |
492 { | 492 { |
493 assert(chunk_idx <= chunk_count(), "bad arg"); | 493 assert(region_idx <= region_count(), "bad arg"); |
494 return _chunk_data + chunk_idx; | 494 return _region_data + region_idx; |
495 } | 495 } |
496 | 496 |
497 inline size_t | 497 inline size_t |
498 ParallelCompactData::chunk(const ChunkData* const chunk_ptr) const | 498 ParallelCompactData::region(const RegionData* const region_ptr) const |
499 { | 499 { |
500 assert(chunk_ptr >= _chunk_data, "bad arg"); | 500 assert(region_ptr >= _region_data, "bad arg"); |
501 assert(chunk_ptr <= _chunk_data + chunk_count(), "bad arg"); | 501 assert(region_ptr <= _region_data + region_count(), "bad arg"); |
502 return pointer_delta(chunk_ptr, _chunk_data, sizeof(ChunkData)); | 502 return pointer_delta(region_ptr, _region_data, sizeof(RegionData)); |
503 } | 503 } |
504 | 504 |
505 inline ParallelCompactData::BlockData* | 505 inline ParallelCompactData::BlockData* |
506 ParallelCompactData::block(size_t n) const { | 506 ParallelCompactData::block(size_t n) const { |
507 assert(n < block_count(), "bad arg"); | 507 assert(n < block_count(), "bad arg"); |
508 return _block_data + n; | 508 return _block_data + n; |
509 } | 509 } |
510 | 510 |
511 inline size_t | 511 inline size_t |
512 ParallelCompactData::chunk_offset(const HeapWord* addr) const | 512 ParallelCompactData::region_offset(const HeapWord* addr) const |
513 { | 513 { |
514 assert(addr >= _region_start, "bad addr"); | 514 assert(addr >= _region_start, "bad addr"); |
515 assert(addr <= _region_end, "bad addr"); | 515 assert(addr <= _region_end, "bad addr"); |
516 return (size_t(addr) & ChunkAddrOffsetMask) >> LogHeapWordSize; | 516 return (size_t(addr) & RegionAddrOffsetMask) >> LogHeapWordSize; |
517 } | 517 } |
518 | 518 |
519 inline size_t | 519 inline size_t |
520 ParallelCompactData::addr_to_chunk_idx(const HeapWord* addr) const | 520 ParallelCompactData::addr_to_region_idx(const HeapWord* addr) const |
521 { | 521 { |
522 assert(addr >= _region_start, "bad addr"); | 522 assert(addr >= _region_start, "bad addr"); |
523 assert(addr <= _region_end, "bad addr"); | 523 assert(addr <= _region_end, "bad addr"); |
524 return pointer_delta(addr, _region_start) >> Log2ChunkSize; | 524 return pointer_delta(addr, _region_start) >> Log2RegionSize; |
525 } | 525 } |
526 | 526 |
527 inline ParallelCompactData::ChunkData* | 527 inline ParallelCompactData::RegionData* |
528 ParallelCompactData::addr_to_chunk_ptr(const HeapWord* addr) const | 528 ParallelCompactData::addr_to_region_ptr(const HeapWord* addr) const |
529 { | 529 { |
530 return chunk(addr_to_chunk_idx(addr)); | 530 return region(addr_to_region_idx(addr)); |
531 } | 531 } |
532 | 532 |
533 inline HeapWord* | 533 inline HeapWord* |
534 ParallelCompactData::chunk_to_addr(size_t chunk) const | 534 ParallelCompactData::region_to_addr(size_t region) const |
535 { | 535 { |
536 assert(chunk <= _chunk_count, "chunk out of range"); | 536 assert(region <= _region_count, "region out of range"); |
537 return _region_start + (chunk << Log2ChunkSize); | 537 return _region_start + (region << Log2RegionSize); |
538 } | 538 } |
539 | 539 |
540 inline HeapWord* | 540 inline HeapWord* |
541 ParallelCompactData::chunk_to_addr(const ChunkData* chunk) const | 541 ParallelCompactData::region_to_addr(const RegionData* region) const |
542 { | 542 { |
543 return chunk_to_addr(pointer_delta(chunk, _chunk_data, sizeof(ChunkData))); | 543 return region_to_addr(pointer_delta(region, _region_data, |
544 sizeof(RegionData))); | |
544 } | 545 } |
545 | 546 |
546 inline HeapWord* | 547 inline HeapWord* |
547 ParallelCompactData::chunk_to_addr(size_t chunk, size_t offset) const | 548 ParallelCompactData::region_to_addr(size_t region, size_t offset) const |
548 { | 549 { |
549 assert(chunk <= _chunk_count, "chunk out of range"); | 550 assert(region <= _region_count, "region out of range"); |
550 assert(offset < ChunkSize, "offset too big"); // This may be too strict. | 551 assert(offset < RegionSize, "offset too big"); // This may be too strict. |
551 return chunk_to_addr(chunk) + offset; | 552 return region_to_addr(region) + offset; |
552 } | 553 } |
553 | 554 |
554 inline HeapWord* | 555 inline HeapWord* |
555 ParallelCompactData::chunk_align_down(HeapWord* addr) const | 556 ParallelCompactData::region_align_down(HeapWord* addr) const |
556 { | 557 { |
557 assert(addr >= _region_start, "bad addr"); | 558 assert(addr >= _region_start, "bad addr"); |
558 assert(addr < _region_end + ChunkSize, "bad addr"); | 559 assert(addr < _region_end + RegionSize, "bad addr"); |
559 return (HeapWord*)(size_t(addr) & ChunkAddrMask); | 560 return (HeapWord*)(size_t(addr) & RegionAddrMask); |
560 } | 561 } |
561 | 562 |
562 inline HeapWord* | 563 inline HeapWord* |
563 ParallelCompactData::chunk_align_up(HeapWord* addr) const | 564 ParallelCompactData::region_align_up(HeapWord* addr) const |
564 { | 565 { |
565 assert(addr >= _region_start, "bad addr"); | 566 assert(addr >= _region_start, "bad addr"); |
566 assert(addr <= _region_end, "bad addr"); | 567 assert(addr <= _region_end, "bad addr"); |
567 return chunk_align_down(addr + ChunkSizeOffsetMask); | 568 return region_align_down(addr + RegionSizeOffsetMask); |
568 } | 569 } |
569 | 570 |
570 inline bool | 571 inline bool |
571 ParallelCompactData::is_chunk_aligned(HeapWord* addr) const | 572 ParallelCompactData::is_region_aligned(HeapWord* addr) const |
572 { | 573 { |
573 return chunk_offset(addr) == 0; | 574 return region_offset(addr) == 0; |
574 } | 575 } |
575 | 576 |
576 inline size_t | 577 inline size_t |
577 ParallelCompactData::block_offset(const HeapWord* addr) const | 578 ParallelCompactData::block_offset(const HeapWord* addr) const |
578 { | 579 { |
690 // Closure for updating the block data during the summary phase. | 691 // Closure for updating the block data during the summary phase. |
691 class BitBlockUpdateClosure: public ParMarkBitMapClosure { | 692 class BitBlockUpdateClosure: public ParMarkBitMapClosure { |
692 // ParallelCompactData::BlockData::blk_ofs_t _live_data_left; | 693 // ParallelCompactData::BlockData::blk_ofs_t _live_data_left; |
693 size_t _live_data_left; | 694 size_t _live_data_left; |
694 size_t _cur_block; | 695 size_t _cur_block; |
695 HeapWord* _chunk_start; | 696 HeapWord* _region_start; |
696 HeapWord* _chunk_end; | 697 HeapWord* _region_end; |
697 size_t _chunk_index; | 698 size_t _region_index; |
698 | 699 |
699 public: | 700 public: |
700 BitBlockUpdateClosure(ParMarkBitMap* mbm, | 701 BitBlockUpdateClosure(ParMarkBitMap* mbm, |
701 ParCompactionManager* cm, | 702 ParCompactionManager* cm, |
702 size_t chunk_index); | 703 size_t region_index); |
703 | 704 |
704 size_t cur_block() { return _cur_block; } | 705 size_t cur_block() { return _cur_block; } |
705 size_t chunk_index() { return _chunk_index; } | 706 size_t region_index() { return _region_index; } |
706 size_t live_data_left() { return _live_data_left; } | 707 size_t live_data_left() { return _live_data_left; } |
707 // Returns true the first bit in the current block (cur_block) is | 708 // Returns true the first bit in the current block (cur_block) is |
708 // a start bit. | 709 // a start bit. |
709 // Returns true if the current block is within the chunk for the closure; | 710 // Returns true if the current block is within the region for the closure; |
710 bool chunk_contains_cur_block(); | 711 bool region_contains_cur_block(); |
711 | 712 |
712 // Set the chunk index and related chunk values for | 713 // Set the region index and related region values for |
713 // a new chunk. | 714 // a new region. |
714 void reset_chunk(size_t chunk_index); | 715 void reset_region(size_t region_index); |
715 | 716 |
716 virtual IterationStatus do_addr(HeapWord* addr, size_t words); | 717 virtual IterationStatus do_addr(HeapWord* addr, size_t words); |
717 }; | 718 }; |
718 | 719 |
719 // The UseParallelOldGC collector is a stop-the-world garbage | 720 // The UseParallelOldGC collector is a stop-the-world garbage collector that |
720 // collector that does parts of the collection using parallel threads. | 721 // does parts of the collection using parallel threads. The collection includes |
721 // The collection includes the tenured generation and the young | 722 // the tenured generation and the young generation. The permanent generation is |
722 // generation. The permanent generation is collected at the same | 723 // collected at the same time as the other two generations but the permanent |
723 // time as the other two generations but the permanent generation | 724 // generation is collect by a single GC thread. The permanent generation is |
724 // is collect by a single GC thread. The permanent generation is | 725 // collected serially because of the requirement that during the processing of a |
725 // collected serially because of the requirement that during the | 726 // klass AAA, any objects reference by AAA must already have been processed. |
726 // processing of a klass AAA, any objects reference by AAA must | 727 // This requirement is enforced by a left (lower address) to right (higher |
727 // already have been processed. This requirement is enforced by | 728 // address) sliding compaction. |
728 // a left (lower address) to right (higher address) sliding compaction. | |
729 // | 729 // |
730 // There are four phases of the collection. | 730 // There are four phases of the collection. |
731 // | 731 // |
732 // - marking phase | 732 // - marking phase |
733 // - summary phase | 733 // - summary phase |
738 // - mark all the live objects | 738 // - mark all the live objects |
739 // - calculate the destination of each object at the end of the collection | 739 // - calculate the destination of each object at the end of the collection |
740 // - move the objects to their destination | 740 // - move the objects to their destination |
741 // - update some references and reinitialize some variables | 741 // - update some references and reinitialize some variables |
742 // | 742 // |
743 // These three phases are invoked in PSParallelCompact::invoke_no_policy(). | 743 // These three phases are invoked in PSParallelCompact::invoke_no_policy(). The |
744 // The marking phase is implemented in PSParallelCompact::marking_phase() | 744 // marking phase is implemented in PSParallelCompact::marking_phase() and does a |
745 // and does a complete marking of the heap. | 745 // complete marking of the heap. The summary phase is implemented in |
746 // The summary phase is implemented in PSParallelCompact::summary_phase(). | 746 // PSParallelCompact::summary_phase(). The move and update phase is implemented |
747 // The move and update phase is implemented in PSParallelCompact::compact(). | 747 // in PSParallelCompact::compact(). |
748 // | 748 // |
749 // A space that is being collected is divided into chunks and with | 749 // A space that is being collected is divided into regions and with each region |
750 // each chunk is associated an object of type ParallelCompactData. | 750 // is associated an object of type ParallelCompactData. Each region is of a |
751 // Each chunk is of a fixed size and typically will contain more than | 751 // fixed size and typically will contain more than 1 object and may have parts |
752 // 1 object and may have parts of objects at the front and back of the | 752 // of objects at the front and back of the region. |
753 // chunk. | |
754 // | 753 // |
755 // chunk -----+---------------------+---------- | 754 // region -----+---------------------+---------- |
756 // objects covered [ AAA )[ BBB )[ CCC )[ DDD ) | 755 // objects covered [ AAA )[ BBB )[ CCC )[ DDD ) |
757 // | 756 // |
758 // The marking phase does a complete marking of all live objects in the | 757 // The marking phase does a complete marking of all live objects in the heap. |
759 // heap. The marking also compiles the size of the data for | 758 // The marking also compiles the size of the data for all live objects covered |
760 // all live objects covered by the chunk. This size includes the | 759 // by the region. This size includes the part of any live object spanning onto |
761 // part of any live object spanning onto the chunk (part of AAA | 760 // the region (part of AAA if it is live) from the front, all live objects |
762 // if it is live) from the front, all live objects contained in the chunk | 761 // contained in the region (BBB and/or CCC if they are live), and the part of |
763 // (BBB and/or CCC if they are live), and the part of any live objects | 762 // any live objects covered by the region that extends off the region (part of |
764 // covered by the chunk that extends off the chunk (part of DDD if it is | 763 // DDD if it is live). The marking phase uses multiple GC threads and marking |
765 // live). The marking phase uses multiple GC threads and marking is | 764 // is done in a bit array of type ParMarkBitMap. The marking of the bit map is |
766 // done in a bit array of type ParMarkBitMap. The marking of the | 765 // done atomically as is the accumulation of the size of the live objects |
767 // bit map is done atomically as is the accumulation of the size of the | 766 // covered by a region. |
768 // live objects covered by a chunk. | |
769 // | 767 // |
770 // The summary phase calculates the total live data to the left of | 768 // The summary phase calculates the total live data to the left of each region |
771 // each chunk XXX. Based on that total and the bottom of the space, | 769 // XXX. Based on that total and the bottom of the space, it can calculate the |
772 // it can calculate the starting location of the live data in XXX. | 770 // starting location of the live data in XXX. The summary phase calculates for |
773 // The summary phase calculates for each chunk XXX quantites such as | 771 // each region XXX quantites such as |
774 // | 772 // |
775 // - the amount of live data at the beginning of a chunk from an object | 773 // - the amount of live data at the beginning of a region from an object |
776 // entering the chunk. | 774 // entering the region. |
777 // - the location of the first live data on the chunk | 775 // - the location of the first live data on the region |
778 // - a count of the number of chunks receiving live data from XXX. | 776 // - a count of the number of regions receiving live data from XXX. |
779 // | 777 // |
780 // See ParallelCompactData for precise details. The summary phase also | 778 // See ParallelCompactData for precise details. The summary phase also |
781 // calculates the dense prefix for the compaction. The dense prefix | 779 // calculates the dense prefix for the compaction. The dense prefix is a |
782 // is a portion at the beginning of the space that is not moved. The | 780 // portion at the beginning of the space that is not moved. The objects in the |
783 // objects in the dense prefix do need to have their object references | 781 // dense prefix do need to have their object references updated. See method |
784 // updated. See method summarize_dense_prefix(). | 782 // summarize_dense_prefix(). |
785 // | 783 // |
786 // The summary phase is done using 1 GC thread. | 784 // The summary phase is done using 1 GC thread. |
787 // | 785 // |
788 // The compaction phase moves objects to their new location and updates | 786 // The compaction phase moves objects to their new location and updates all |
789 // all references in the object. | 787 // references in the object. |
790 // | 788 // |
791 // A current exception is that objects that cross a chunk boundary | 789 // A current exception is that objects that cross a region boundary are moved |
792 // are moved but do not have their references updated. References are | 790 // but do not have their references updated. References are not updated because |
793 // not updated because it cannot easily be determined if the klass | 791 // it cannot easily be determined if the klass pointer KKK for the object AAA |
794 // pointer KKK for the object AAA has been updated. KKK likely resides | 792 // has been updated. KKK likely resides in a region to the left of the region |
795 // in a chunk to the left of the chunk containing AAA. These AAA's | 793 // containing AAA. These AAA's have there references updated at the end in a |
796 // have there references updated at the end in a clean up phase. | 794 // clean up phase. See the method PSParallelCompact::update_deferred_objects(). |
797 // See the method PSParallelCompact::update_deferred_objects(). An | 795 // An alternate strategy is being investigated for this deferral of updating. |
798 // alternate strategy is being investigated for this deferral of updating. | |
799 // | 796 // |
800 // Compaction is done on a chunk basis. A chunk that is ready to be | 797 // Compaction is done on a region basis. A region that is ready to be filled is |
801 // filled is put on a ready list and GC threads take chunk off the list | 798 // put on a ready list and GC threads take region off the list and fill them. A |
802 // and fill them. A chunk is ready to be filled if it | 799 // region is ready to be filled if it empty of live objects. Such a region may |
803 // empty of live objects. Such a chunk may have been initially | 800 // have been initially empty (only contained dead objects) or may have had all |
804 // empty (only contained | 801 // its live objects copied out already. A region that compacts into itself is |
805 // dead objects) or may have had all its live objects copied out already. | 802 // also ready for filling. The ready list is initially filled with empty |
806 // A chunk that compacts into itself is also ready for filling. The | 803 // regions and regions compacting into themselves. There is always at least 1 |
807 // ready list is initially filled with empty chunks and chunks compacting | 804 // region that can be put on the ready list. The regions are atomically added |
808 // into themselves. There is always at least 1 chunk that can be put on | 805 // and removed from the ready list. |
809 // the ready list. The chunks are atomically added and removed from | 806 |
810 // the ready list. | |
811 // | |
812 class PSParallelCompact : AllStatic { | 807 class PSParallelCompact : AllStatic { |
813 public: | 808 public: |
814 // Convenient access to type names. | 809 // Convenient access to type names. |
815 typedef ParMarkBitMap::idx_t idx_t; | 810 typedef ParMarkBitMap::idx_t idx_t; |
816 typedef ParallelCompactData::ChunkData ChunkData; | 811 typedef ParallelCompactData::RegionData RegionData; |
817 typedef ParallelCompactData::BlockData BlockData; | 812 typedef ParallelCompactData::BlockData BlockData; |
818 | 813 |
819 typedef enum { | 814 typedef enum { |
820 perm_space_id, old_space_id, eden_space_id, | 815 perm_space_id, old_space_id, eden_space_id, |
821 from_space_id, to_space_id, last_space_id | 816 from_space_id, to_space_id, last_space_id |
975 | 970 |
976 // Return the percentage of space that can be treated as "dead wood" (i.e., | 971 // Return the percentage of space that can be treated as "dead wood" (i.e., |
977 // not reclaimed). | 972 // not reclaimed). |
978 static double dead_wood_limiter(double density, size_t min_percent); | 973 static double dead_wood_limiter(double density, size_t min_percent); |
979 | 974 |
980 // Find the first (left-most) chunk in the range [beg, end) that has at least | 975 // Find the first (left-most) region in the range [beg, end) that has at least |
981 // dead_words of dead space to the left. The argument beg must be the first | 976 // dead_words of dead space to the left. The argument beg must be the first |
982 // chunk in the space that is not completely live. | 977 // region in the space that is not completely live. |
983 static ChunkData* dead_wood_limit_chunk(const ChunkData* beg, | 978 static RegionData* dead_wood_limit_region(const RegionData* beg, |
984 const ChunkData* end, | 979 const RegionData* end, |
985 size_t dead_words); | 980 size_t dead_words); |
986 | 981 |
987 // Return a pointer to the first chunk in the range [beg, end) that is not | 982 // Return a pointer to the first region in the range [beg, end) that is not |
988 // completely full. | 983 // completely full. |
989 static ChunkData* first_dead_space_chunk(const ChunkData* beg, | 984 static RegionData* first_dead_space_region(const RegionData* beg, |
990 const ChunkData* end); | 985 const RegionData* end); |
991 | 986 |
992 // Return a value indicating the benefit or 'yield' if the compacted region | 987 // Return a value indicating the benefit or 'yield' if the compacted region |
993 // were to start (or equivalently if the dense prefix were to end) at the | 988 // were to start (or equivalently if the dense prefix were to end) at the |
994 // candidate chunk. Higher values are better. | 989 // candidate region. Higher values are better. |
995 // | 990 // |
996 // The value is based on the amount of space reclaimed vs. the costs of (a) | 991 // The value is based on the amount of space reclaimed vs. the costs of (a) |
997 // updating references in the dense prefix plus (b) copying objects and | 992 // updating references in the dense prefix plus (b) copying objects and |
998 // updating references in the compacted region. | 993 // updating references in the compacted region. |
999 static inline double reclaimed_ratio(const ChunkData* const candidate, | 994 static inline double reclaimed_ratio(const RegionData* const candidate, |
1000 HeapWord* const bottom, | 995 HeapWord* const bottom, |
1001 HeapWord* const top, | 996 HeapWord* const top, |
1002 HeapWord* const new_top); | 997 HeapWord* const new_top); |
1003 | 998 |
1004 // Compute the dense prefix for the designated space. | 999 // Compute the dense prefix for the designated space. |
1005 static HeapWord* compute_dense_prefix(const SpaceId id, | 1000 static HeapWord* compute_dense_prefix(const SpaceId id, |
1006 bool maximum_compaction); | 1001 bool maximum_compaction); |
1007 | 1002 |
1008 // Return true if dead space crosses onto the specified Chunk; bit must be the | 1003 // Return true if dead space crosses onto the specified Region; bit must be |
1009 // bit index corresponding to the first word of the Chunk. | 1004 // the bit index corresponding to the first word of the Region. |
1010 static inline bool dead_space_crosses_boundary(const ChunkData* chunk, | 1005 static inline bool dead_space_crosses_boundary(const RegionData* region, |
1011 idx_t bit); | 1006 idx_t bit); |
1012 | 1007 |
1013 // Summary phase utility routine to fill dead space (if any) at the dense | 1008 // Summary phase utility routine to fill dead space (if any) at the dense |
1014 // prefix boundary. Should only be called if the the dense prefix is | 1009 // prefix boundary. Should only be called if the the dense prefix is |
1015 // non-empty. | 1010 // non-empty. |
1036 | 1031 |
1037 // Move objects to new locations. | 1032 // Move objects to new locations. |
1038 static void compact_perm(ParCompactionManager* cm); | 1033 static void compact_perm(ParCompactionManager* cm); |
1039 static void compact(); | 1034 static void compact(); |
1040 | 1035 |
1041 // Add available chunks to the stack and draining tasks to the task queue. | 1036 // Add available regions to the stack and draining tasks to the task queue. |
1042 static void enqueue_chunk_draining_tasks(GCTaskQueue* q, | 1037 static void enqueue_region_draining_tasks(GCTaskQueue* q, |
1043 uint parallel_gc_threads); | 1038 uint parallel_gc_threads); |
1044 | 1039 |
1045 // Add dense prefix update tasks to the task queue. | 1040 // Add dense prefix update tasks to the task queue. |
1046 static void enqueue_dense_prefix_tasks(GCTaskQueue* q, | 1041 static void enqueue_dense_prefix_tasks(GCTaskQueue* q, |
1047 uint parallel_gc_threads); | 1042 uint parallel_gc_threads); |
1048 | 1043 |
1049 // Add chunk stealing tasks to the task queue. | 1044 // Add region stealing tasks to the task queue. |
1050 static void enqueue_chunk_stealing_tasks( | 1045 static void enqueue_region_stealing_tasks( |
1051 GCTaskQueue* q, | 1046 GCTaskQueue* q, |
1052 ParallelTaskTerminator* terminator_ptr, | 1047 ParallelTaskTerminator* terminator_ptr, |
1053 uint parallel_gc_threads); | 1048 uint parallel_gc_threads); |
1054 | 1049 |
1055 // For debugging only - compacts the old gen serially | 1050 // For debugging only - compacts the old gen serially |
1152 static inline bool should_update_klass(klassOop k); | 1147 static inline bool should_update_klass(klassOop k); |
1153 | 1148 |
1154 // Move and update the live objects in the specified space. | 1149 // Move and update the live objects in the specified space. |
1155 static void move_and_update(ParCompactionManager* cm, SpaceId space_id); | 1150 static void move_and_update(ParCompactionManager* cm, SpaceId space_id); |
1156 | 1151 |
1157 // Process the end of the given chunk range in the dense prefix. | 1152 // Process the end of the given region range in the dense prefix. |
1158 // This includes saving any object not updated. | 1153 // This includes saving any object not updated. |
1159 static void dense_prefix_chunks_epilogue(ParCompactionManager* cm, | 1154 static void dense_prefix_regions_epilogue(ParCompactionManager* cm, |
1160 size_t chunk_start_index, | 1155 size_t region_start_index, |
1161 size_t chunk_end_index, | 1156 size_t region_end_index, |
1162 idx_t exiting_object_offset, | 1157 idx_t exiting_object_offset, |
1163 idx_t chunk_offset_start, | 1158 idx_t region_offset_start, |
1164 idx_t chunk_offset_end); | 1159 idx_t region_offset_end); |
1165 | 1160 |
1166 // Update a chunk in the dense prefix. For each live object | 1161 // Update a region in the dense prefix. For each live object |
1167 // in the chunk, update it's interior references. For each | 1162 // in the region, update it's interior references. For each |
1168 // dead object, fill it with deadwood. Dead space at the end | 1163 // dead object, fill it with deadwood. Dead space at the end |
1169 // of a chunk range will be filled to the start of the next | 1164 // of a region range will be filled to the start of the next |
1170 // live object regardless of the chunk_index_end. None of the | 1165 // live object regardless of the region_index_end. None of the |
1171 // objects in the dense prefix move and dead space is dead | 1166 // objects in the dense prefix move and dead space is dead |
1172 // (holds only dead objects that don't need any processing), so | 1167 // (holds only dead objects that don't need any processing), so |
1173 // dead space can be filled in any order. | 1168 // dead space can be filled in any order. |
1174 static void update_and_deadwood_in_dense_prefix(ParCompactionManager* cm, | 1169 static void update_and_deadwood_in_dense_prefix(ParCompactionManager* cm, |
1175 SpaceId space_id, | 1170 SpaceId space_id, |
1176 size_t chunk_index_start, | 1171 size_t region_index_start, |
1177 size_t chunk_index_end); | 1172 size_t region_index_end); |
1178 | 1173 |
1179 // Return the address of the count + 1st live word in the range [beg, end). | 1174 // Return the address of the count + 1st live word in the range [beg, end). |
1180 static HeapWord* skip_live_words(HeapWord* beg, HeapWord* end, size_t count); | 1175 static HeapWord* skip_live_words(HeapWord* beg, HeapWord* end, size_t count); |
1181 | 1176 |
1182 // Return the address of the word to be copied to dest_addr, which must be | 1177 // Return the address of the word to be copied to dest_addr, which must be |
1183 // aligned to a chunk boundary. | 1178 // aligned to a region boundary. |
1184 static HeapWord* first_src_addr(HeapWord* const dest_addr, | 1179 static HeapWord* first_src_addr(HeapWord* const dest_addr, |
1185 size_t src_chunk_idx); | 1180 size_t src_region_idx); |
1186 | 1181 |
1187 // Determine the next source chunk, set closure.source() to the start of the | 1182 // Determine the next source region, set closure.source() to the start of the |
1188 // new chunk return the chunk index. Parameter end_addr is the address one | 1183 // new region return the region index. Parameter end_addr is the address one |
1189 // beyond the end of source range just processed. If necessary, switch to a | 1184 // beyond the end of source range just processed. If necessary, switch to a |
1190 // new source space and set src_space_id (in-out parameter) and src_space_top | 1185 // new source space and set src_space_id (in-out parameter) and src_space_top |
1191 // (out parameter) accordingly. | 1186 // (out parameter) accordingly. |
1192 static size_t next_src_chunk(MoveAndUpdateClosure& closure, | 1187 static size_t next_src_region(MoveAndUpdateClosure& closure, |
1193 SpaceId& src_space_id, | 1188 SpaceId& src_space_id, |
1194 HeapWord*& src_space_top, | 1189 HeapWord*& src_space_top, |
1195 HeapWord* end_addr); | 1190 HeapWord* end_addr); |
1196 | 1191 |
1197 // Decrement the destination count for each non-empty source chunk in the | 1192 // Decrement the destination count for each non-empty source region in the |
1198 // range [beg_chunk, chunk(chunk_align_up(end_addr))). | 1193 // range [beg_region, region(region_align_up(end_addr))). |
1199 static void decrement_destination_counts(ParCompactionManager* cm, | 1194 static void decrement_destination_counts(ParCompactionManager* cm, |
1200 size_t beg_chunk, | 1195 size_t beg_region, |
1201 HeapWord* end_addr); | 1196 HeapWord* end_addr); |
1202 | 1197 |
1203 // Fill a chunk, copying objects from one or more source chunks. | 1198 // Fill a region, copying objects from one or more source regions. |
1204 static void fill_chunk(ParCompactionManager* cm, size_t chunk_idx); | 1199 static void fill_region(ParCompactionManager* cm, size_t region_idx); |
1205 static void fill_and_update_chunk(ParCompactionManager* cm, size_t chunk) { | 1200 static void fill_and_update_region(ParCompactionManager* cm, size_t region) { |
1206 fill_chunk(cm, chunk); | 1201 fill_region(cm, region); |
1207 } | 1202 } |
1208 | 1203 |
1209 // Update the deferred objects in the space. | 1204 // Update the deferred objects in the space. |
1210 static void update_deferred_objects(ParCompactionManager* cm, SpaceId id); | 1205 static void update_deferred_objects(ParCompactionManager* cm, SpaceId id); |
1211 | 1206 |
1257 static void revisit_weak_klass_link(ParCompactionManager* cm, Klass* k); | 1252 static void revisit_weak_klass_link(ParCompactionManager* cm, Klass* k); |
1258 | 1253 |
1259 #ifndef PRODUCT | 1254 #ifndef PRODUCT |
1260 // Debugging support. | 1255 // Debugging support. |
1261 static const char* space_names[last_space_id]; | 1256 static const char* space_names[last_space_id]; |
1262 static void print_chunk_ranges(); | 1257 static void print_region_ranges(); |
1263 static void print_dense_prefix_stats(const char* const algorithm, | 1258 static void print_dense_prefix_stats(const char* const algorithm, |
1264 const SpaceId id, | 1259 const SpaceId id, |
1265 const bool maximum_compaction, | 1260 const bool maximum_compaction, |
1266 HeapWord* const addr); | 1261 HeapWord* const addr); |
1267 #endif // #ifndef PRODUCT | 1262 #endif // #ifndef PRODUCT |
1268 | 1263 |
1269 #ifdef ASSERT | 1264 #ifdef ASSERT |
1270 // Verify that all the chunks have been emptied. | 1265 // Verify that all the regions have been emptied. |
1271 static void verify_complete(SpaceId space_id); | 1266 static void verify_complete(SpaceId space_id); |
1272 #endif // #ifdef ASSERT | 1267 #endif // #ifdef ASSERT |
1273 }; | 1268 }; |
1274 | 1269 |
1275 inline bool PSParallelCompact::mark_obj(oop obj) { | 1270 inline bool PSParallelCompact::mark_obj(oop obj) { |
1374 const double squared_term = (density - _dwl_mean) / _dwl_std_dev; | 1369 const double squared_term = (density - _dwl_mean) / _dwl_std_dev; |
1375 return _dwl_first_term * exp(-0.5 * squared_term * squared_term); | 1370 return _dwl_first_term * exp(-0.5 * squared_term * squared_term); |
1376 } | 1371 } |
1377 | 1372 |
1378 inline bool | 1373 inline bool |
1379 PSParallelCompact::dead_space_crosses_boundary(const ChunkData* chunk, | 1374 PSParallelCompact::dead_space_crosses_boundary(const RegionData* region, |
1380 idx_t bit) | 1375 idx_t bit) |
1381 { | 1376 { |
1382 assert(bit > 0, "cannot call this for the first bit/chunk"); | 1377 assert(bit > 0, "cannot call this for the first bit/region"); |
1383 assert(_summary_data.chunk_to_addr(chunk) == _mark_bitmap.bit_to_addr(bit), | 1378 assert(_summary_data.region_to_addr(region) == _mark_bitmap.bit_to_addr(bit), |
1384 "sanity check"); | 1379 "sanity check"); |
1385 | 1380 |
1386 // Dead space crosses the boundary if (1) a partial object does not extend | 1381 // Dead space crosses the boundary if (1) a partial object does not extend |
1387 // onto the chunk, (2) an object does not start at the beginning of the chunk, | 1382 // onto the region, (2) an object does not start at the beginning of the |
1388 // and (3) an object does not end at the end of the prior chunk. | 1383 // region, and (3) an object does not end at the end of the prior region. |
1389 return chunk->partial_obj_size() == 0 && | 1384 return region->partial_obj_size() == 0 && |
1390 !_mark_bitmap.is_obj_beg(bit) && | 1385 !_mark_bitmap.is_obj_beg(bit) && |
1391 !_mark_bitmap.is_obj_end(bit - 1); | 1386 !_mark_bitmap.is_obj_end(bit - 1); |
1392 } | 1387 } |
1393 | 1388 |
1394 inline bool | 1389 inline bool |