Mercurial > hg > graal-compiler
comparison src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp @ 10369:5534bd30c151
6725714: par compact - add a table to speed up bitmap searches
Reviewed-by: jmasa, tschatzl
author | jcoomes |
---|---|
date | Thu, 30 May 2013 13:04:51 -0700 |
parents | 10f759898d40 |
children | f2110083203d |
comparison
equal
deleted
inserted
replaced
10363:8dbc025ff709 | 10369:5534bd30c151 |
---|---|
218 // Mask for the bits in a pointer to get an offset within a region. | 218 // Mask for the bits in a pointer to get an offset within a region. |
219 static const size_t RegionAddrOffsetMask; | 219 static const size_t RegionAddrOffsetMask; |
220 // Mask for the bits in a pointer to get the address of the start of a region. | 220 // Mask for the bits in a pointer to get the address of the start of a region. |
221 static const size_t RegionAddrMask; | 221 static const size_t RegionAddrMask; |
222 | 222 |
223 static const size_t Log2BlockSize; | |
224 static const size_t BlockSize; | |
225 static const size_t BlockSizeBytes; | |
226 | |
227 static const size_t BlockSizeOffsetMask; | |
228 static const size_t BlockAddrOffsetMask; | |
229 static const size_t BlockAddrMask; | |
230 | |
231 static const size_t BlocksPerRegion; | |
232 static const size_t Log2BlocksPerRegion; | |
233 | |
223 class RegionData | 234 class RegionData |
224 { | 235 { |
225 public: | 236 public: |
226 // Destination address of the region. | 237 // Destination address of the region. |
227 HeapWord* destination() const { return _destination; } | 238 HeapWord* destination() const { return _destination; } |
270 // been filled, the destination_count should be set to the completed value | 281 // been filled, the destination_count should be set to the completed value |
271 // (dc_completed). | 282 // (dc_completed). |
272 inline uint destination_count() const; | 283 inline uint destination_count() const; |
273 inline uint destination_count_raw() const; | 284 inline uint destination_count_raw() const; |
274 | 285 |
286 // Whether the block table for this region has been filled. | |
287 inline bool blocks_filled() const; | |
288 | |
289 // Number of times the block table was filled. | |
290 DEBUG_ONLY(inline size_t blocks_filled_count() const;) | |
291 | |
275 // The location of the java heap data that corresponds to this region. | 292 // The location of the java heap data that corresponds to this region. |
276 inline HeapWord* data_location() const; | 293 inline HeapWord* data_location() const; |
277 | 294 |
278 // The highest address referenced by objects in this region. | 295 // The highest address referenced by objects in this region. |
279 inline HeapWord* highest_ref() const; | 296 inline HeapWord* highest_ref() const; |
294 void set_deferred_obj_addr(HeapWord* addr) { _partial_obj_addr = addr; } | 311 void set_deferred_obj_addr(HeapWord* addr) { _partial_obj_addr = addr; } |
295 void set_partial_obj_addr(HeapWord* addr) { _partial_obj_addr = addr; } | 312 void set_partial_obj_addr(HeapWord* addr) { _partial_obj_addr = addr; } |
296 void set_partial_obj_size(size_t words) { | 313 void set_partial_obj_size(size_t words) { |
297 _partial_obj_size = (region_sz_t) words; | 314 _partial_obj_size = (region_sz_t) words; |
298 } | 315 } |
316 inline void set_blocks_filled(); | |
299 | 317 |
300 inline void set_destination_count(uint count); | 318 inline void set_destination_count(uint count); |
301 inline void set_live_obj_size(size_t words); | 319 inline void set_live_obj_size(size_t words); |
302 inline void set_data_location(HeapWord* addr); | 320 inline void set_data_location(HeapWord* addr); |
303 inline void set_completed(); | 321 inline void set_completed(); |
326 HeapWord* _destination; | 344 HeapWord* _destination; |
327 size_t _source_region; | 345 size_t _source_region; |
328 HeapWord* _partial_obj_addr; | 346 HeapWord* _partial_obj_addr; |
329 region_sz_t _partial_obj_size; | 347 region_sz_t _partial_obj_size; |
330 region_sz_t volatile _dc_and_los; | 348 region_sz_t volatile _dc_and_los; |
349 bool _blocks_filled; | |
350 | |
331 #ifdef ASSERT | 351 #ifdef ASSERT |
352 size_t _blocks_filled_count; // Number of block table fills. | |
353 | |
332 // These enable optimizations that are only partially implemented. Use | 354 // These enable optimizations that are only partially implemented. Use |
333 // debug builds to prevent the code fragments from breaking. | 355 // debug builds to prevent the code fragments from breaking. |
334 HeapWord* _data_location; | 356 HeapWord* _data_location; |
335 HeapWord* _highest_ref; | 357 HeapWord* _highest_ref; |
336 #endif // #ifdef ASSERT | 358 #endif // #ifdef ASSERT |
337 | 359 |
338 #ifdef ASSERT | 360 #ifdef ASSERT |
339 public: | 361 public: |
340 uint _pushed; // 0 until region is pushed onto a worker's stack | 362 uint _pushed; // 0 until region is pushed onto a stack |
341 private: | 363 private: |
342 #endif | 364 #endif |
343 }; | 365 }; |
344 | 366 |
367 // "Blocks" allow shorter sections of the bitmap to be searched. Each Block | |
368 // holds an offset, which is the amount of live data in the Region to the left | |
369 // of the first live object that starts in the Block. | |
370 class BlockData | |
371 { | |
372 public: | |
373 typedef unsigned short int blk_ofs_t; | |
374 | |
375 blk_ofs_t offset() const { return _offset; } | |
376 void set_offset(size_t val) { _offset = (blk_ofs_t)val; } | |
377 | |
378 private: | |
379 blk_ofs_t _offset; | |
380 }; | |
381 | |
345 public: | 382 public: |
346 ParallelCompactData(); | 383 ParallelCompactData(); |
347 bool initialize(MemRegion covered_region); | 384 bool initialize(MemRegion covered_region); |
348 | 385 |
349 size_t region_count() const { return _region_count; } | 386 size_t region_count() const { return _region_count; } |
351 | 388 |
352 // Convert region indices to/from RegionData pointers. | 389 // Convert region indices to/from RegionData pointers. |
353 inline RegionData* region(size_t region_idx) const; | 390 inline RegionData* region(size_t region_idx) const; |
354 inline size_t region(const RegionData* const region_ptr) const; | 391 inline size_t region(const RegionData* const region_ptr) const; |
355 | 392 |
356 // Returns true if the given address is contained within the region | 393 size_t block_count() const { return _block_count; } |
357 bool region_contains(size_t region_index, HeapWord* addr); | 394 inline BlockData* block(size_t block_idx) const; |
395 inline size_t block(const BlockData* block_ptr) const; | |
358 | 396 |
359 void add_obj(HeapWord* addr, size_t len); | 397 void add_obj(HeapWord* addr, size_t len); |
360 void add_obj(oop p, size_t len) { add_obj((HeapWord*)p, len); } | 398 void add_obj(oop p, size_t len) { add_obj((HeapWord*)p, len); } |
361 | 399 |
362 // Fill in the regions covering [beg, end) so that no data moves; i.e., the | 400 // Fill in the regions covering [beg, end) so that no data moves; i.e., the |
392 | 430 |
393 inline HeapWord* region_align_down(HeapWord* addr) const; | 431 inline HeapWord* region_align_down(HeapWord* addr) const; |
394 inline HeapWord* region_align_up(HeapWord* addr) const; | 432 inline HeapWord* region_align_up(HeapWord* addr) const; |
395 inline bool is_region_aligned(HeapWord* addr) const; | 433 inline bool is_region_aligned(HeapWord* addr) const; |
396 | 434 |
435 // Analogous to region_offset() for blocks. | |
436 size_t block_offset(const HeapWord* addr) const; | |
437 size_t addr_to_block_idx(const HeapWord* addr) const; | |
438 size_t addr_to_block_idx(const oop obj) const { | |
439 return addr_to_block_idx((HeapWord*) obj); | |
440 } | |
441 inline BlockData* addr_to_block_ptr(const HeapWord* addr) const; | |
442 inline HeapWord* block_to_addr(size_t block) const; | |
443 inline size_t region_to_block_idx(size_t region) const; | |
444 | |
445 inline HeapWord* block_align_down(HeapWord* addr) const; | |
446 inline HeapWord* block_align_up(HeapWord* addr) const; | |
447 inline bool is_block_aligned(HeapWord* addr) const; | |
448 | |
397 // Return the address one past the end of the partial object. | 449 // Return the address one past the end of the partial object. |
398 HeapWord* partial_obj_end(size_t region_idx) const; | 450 HeapWord* partial_obj_end(size_t region_idx) const; |
399 | 451 |
400 // Return the new location of the object p after the | 452 // Return the location of the object after compaction. |
401 // the compaction. | |
402 HeapWord* calc_new_pointer(HeapWord* addr); | 453 HeapWord* calc_new_pointer(HeapWord* addr); |
403 | 454 |
404 HeapWord* calc_new_pointer(oop p) { | 455 HeapWord* calc_new_pointer(oop p) { |
405 return calc_new_pointer((HeapWord*) p); | 456 return calc_new_pointer((HeapWord*) p); |
406 } | 457 } |
409 void verify_clear(const PSVirtualSpace* vspace); | 460 void verify_clear(const PSVirtualSpace* vspace); |
410 void verify_clear(); | 461 void verify_clear(); |
411 #endif // #ifdef ASSERT | 462 #endif // #ifdef ASSERT |
412 | 463 |
413 private: | 464 private: |
465 bool initialize_block_data(); | |
414 bool initialize_region_data(size_t region_size); | 466 bool initialize_region_data(size_t region_size); |
415 PSVirtualSpace* create_vspace(size_t count, size_t element_size); | 467 PSVirtualSpace* create_vspace(size_t count, size_t element_size); |
416 | 468 |
417 private: | 469 private: |
418 HeapWord* _region_start; | 470 HeapWord* _region_start; |
422 | 474 |
423 PSVirtualSpace* _region_vspace; | 475 PSVirtualSpace* _region_vspace; |
424 size_t _reserved_byte_size; | 476 size_t _reserved_byte_size; |
425 RegionData* _region_data; | 477 RegionData* _region_data; |
426 size_t _region_count; | 478 size_t _region_count; |
479 | |
480 PSVirtualSpace* _block_vspace; | |
481 BlockData* _block_data; | |
482 size_t _block_count; | |
427 }; | 483 }; |
428 | 484 |
429 inline uint | 485 inline uint |
430 ParallelCompactData::RegionData::destination_count_raw() const | 486 ParallelCompactData::RegionData::destination_count_raw() const |
431 { | 487 { |
434 | 490 |
435 inline uint | 491 inline uint |
436 ParallelCompactData::RegionData::destination_count() const | 492 ParallelCompactData::RegionData::destination_count() const |
437 { | 493 { |
438 return destination_count_raw() >> dc_shift; | 494 return destination_count_raw() >> dc_shift; |
495 } | |
496 | |
497 inline bool | |
498 ParallelCompactData::RegionData::blocks_filled() const | |
499 { | |
500 return _blocks_filled; | |
501 } | |
502 | |
503 #ifdef ASSERT | |
504 inline size_t | |
505 ParallelCompactData::RegionData::blocks_filled_count() const | |
506 { | |
507 return _blocks_filled_count; | |
508 } | |
509 #endif // #ifdef ASSERT | |
510 | |
511 inline void | |
512 ParallelCompactData::RegionData::set_blocks_filled() | |
513 { | |
514 _blocks_filled = true; | |
515 // Debug builds count the number of times the table was filled. | |
516 DEBUG_ONLY(Atomic::inc_ptr(&_blocks_filled_count)); | |
439 } | 517 } |
440 | 518 |
441 inline void | 519 inline void |
442 ParallelCompactData::RegionData::set_destination_count(uint count) | 520 ParallelCompactData::RegionData::set_destination_count(uint count) |
443 { | 521 { |
530 assert(region_ptr >= _region_data, "bad arg"); | 608 assert(region_ptr >= _region_data, "bad arg"); |
531 assert(region_ptr <= _region_data + region_count(), "bad arg"); | 609 assert(region_ptr <= _region_data + region_count(), "bad arg"); |
532 return pointer_delta(region_ptr, _region_data, sizeof(RegionData)); | 610 return pointer_delta(region_ptr, _region_data, sizeof(RegionData)); |
533 } | 611 } |
534 | 612 |
613 inline ParallelCompactData::BlockData* | |
614 ParallelCompactData::block(size_t n) const { | |
615 assert(n < block_count(), "bad arg"); | |
616 return _block_data + n; | |
617 } | |
618 | |
535 inline size_t | 619 inline size_t |
536 ParallelCompactData::region_offset(const HeapWord* addr) const | 620 ParallelCompactData::region_offset(const HeapWord* addr) const |
537 { | 621 { |
538 assert(addr >= _region_start, "bad addr"); | 622 assert(addr >= _region_start, "bad addr"); |
539 assert(addr <= _region_end, "bad addr"); | 623 assert(addr <= _region_end, "bad addr"); |
594 | 678 |
595 inline bool | 679 inline bool |
596 ParallelCompactData::is_region_aligned(HeapWord* addr) const | 680 ParallelCompactData::is_region_aligned(HeapWord* addr) const |
597 { | 681 { |
598 return region_offset(addr) == 0; | 682 return region_offset(addr) == 0; |
683 } | |
684 | |
685 inline size_t | |
686 ParallelCompactData::block_offset(const HeapWord* addr) const | |
687 { | |
688 assert(addr >= _region_start, "bad addr"); | |
689 assert(addr <= _region_end, "bad addr"); | |
690 return (size_t(addr) & BlockAddrOffsetMask) >> LogHeapWordSize; | |
691 } | |
692 | |
693 inline size_t | |
694 ParallelCompactData::addr_to_block_idx(const HeapWord* addr) const | |
695 { | |
696 assert(addr >= _region_start, "bad addr"); | |
697 assert(addr <= _region_end, "bad addr"); | |
698 return pointer_delta(addr, _region_start) >> Log2BlockSize; | |
699 } | |
700 | |
701 inline ParallelCompactData::BlockData* | |
702 ParallelCompactData::addr_to_block_ptr(const HeapWord* addr) const | |
703 { | |
704 return block(addr_to_block_idx(addr)); | |
705 } | |
706 | |
707 inline HeapWord* | |
708 ParallelCompactData::block_to_addr(size_t block) const | |
709 { | |
710 assert(block < _block_count, "block out of range"); | |
711 return _region_start + (block << Log2BlockSize); | |
712 } | |
713 | |
714 inline size_t | |
715 ParallelCompactData::region_to_block_idx(size_t region) const | |
716 { | |
717 return region << Log2BlocksPerRegion; | |
718 } | |
719 | |
720 inline HeapWord* | |
721 ParallelCompactData::block_align_down(HeapWord* addr) const | |
722 { | |
723 assert(addr >= _region_start, "bad addr"); | |
724 assert(addr < _region_end + RegionSize, "bad addr"); | |
725 return (HeapWord*)(size_t(addr) & BlockAddrMask); | |
726 } | |
727 | |
728 inline HeapWord* | |
729 ParallelCompactData::block_align_up(HeapWord* addr) const | |
730 { | |
731 assert(addr >= _region_start, "bad addr"); | |
732 assert(addr <= _region_end, "bad addr"); | |
733 return block_align_down(addr + BlockSizeOffsetMask); | |
734 } | |
735 | |
736 inline bool | |
737 ParallelCompactData::is_block_aligned(HeapWord* addr) const | |
738 { | |
739 return block_offset(addr) == 0; | |
599 } | 740 } |
600 | 741 |
601 // Abstract closure for use with ParMarkBitMap::iterate(), which will invoke the | 742 // Abstract closure for use with ParMarkBitMap::iterate(), which will invoke the |
602 // do_addr() method. | 743 // do_addr() method. |
603 // | 744 // |
773 class PSParallelCompact : AllStatic { | 914 class PSParallelCompact : AllStatic { |
774 public: | 915 public: |
775 // Convenient access to type names. | 916 // Convenient access to type names. |
776 typedef ParMarkBitMap::idx_t idx_t; | 917 typedef ParMarkBitMap::idx_t idx_t; |
777 typedef ParallelCompactData::RegionData RegionData; | 918 typedef ParallelCompactData::RegionData RegionData; |
919 typedef ParallelCompactData::BlockData BlockData; | |
778 | 920 |
779 typedef enum { | 921 typedef enum { |
780 old_space_id, eden_space_id, | 922 old_space_id, eden_space_id, |
781 from_space_id, to_space_id, last_space_id | 923 from_space_id, to_space_id, last_space_id |
782 } SpaceId; | 924 } SpaceId; |
960 static void summary_phase(ParCompactionManager* cm, bool maximum_compaction); | 1102 static void summary_phase(ParCompactionManager* cm, bool maximum_compaction); |
961 | 1103 |
962 // Adjust addresses in roots. Does not adjust addresses in heap. | 1104 // Adjust addresses in roots. Does not adjust addresses in heap. |
963 static void adjust_roots(); | 1105 static void adjust_roots(); |
964 | 1106 |
1107 DEBUG_ONLY(static void write_block_fill_histogram(outputStream* const out);) | |
1108 | |
965 // Move objects to new locations. | 1109 // Move objects to new locations. |
966 static void compact_perm(ParCompactionManager* cm); | 1110 static void compact_perm(ParCompactionManager* cm); |
967 static void compact(); | 1111 static void compact(); |
968 | 1112 |
969 // Add available regions to the stack and draining tasks to the task queue. | 1113 // Add available regions to the stack and draining tasks to the task queue. |
1125 // Fill a region, copying objects from one or more source regions. | 1269 // Fill a region, copying objects from one or more source regions. |
1126 static void fill_region(ParCompactionManager* cm, size_t region_idx); | 1270 static void fill_region(ParCompactionManager* cm, size_t region_idx); |
1127 static void fill_and_update_region(ParCompactionManager* cm, size_t region) { | 1271 static void fill_and_update_region(ParCompactionManager* cm, size_t region) { |
1128 fill_region(cm, region); | 1272 fill_region(cm, region); |
1129 } | 1273 } |
1274 | |
1275 // Fill in the block table for the specified region. | |
1276 static void fill_blocks(size_t region_idx); | |
1130 | 1277 |
1131 // Update the deferred objects in the space. | 1278 // Update the deferred objects in the space. |
1132 static void update_deferred_objects(ParCompactionManager* cm, SpaceId id); | 1279 static void update_deferred_objects(ParCompactionManager* cm, SpaceId id); |
1133 | 1280 |
1134 static ParMarkBitMap* mark_bitmap() { return &_mark_bitmap; } | 1281 static ParMarkBitMap* mark_bitmap() { return &_mark_bitmap; } |