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. |
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 |