Mercurial > hg > graal-compiler
comparison src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @ 376:0166ac265d53
6729594: par compact - remove unused block table implementation
Reviewed-by: tonyp, jmasa, apetrusenko
author | jcoomes |
---|---|
date | Tue, 30 Sep 2008 13:15:27 -0700 |
parents | 81cd571500b0 |
children | c96030fff130 |
comparison
equal
deleted
inserted
replaced
375:81cd571500b0 | 376:0166ac265d53 |
---|---|
34 RegionSize << LogHeapWordSize; | 34 RegionSize << LogHeapWordSize; |
35 const size_t ParallelCompactData::RegionSizeOffsetMask = RegionSize - 1; | 35 const size_t ParallelCompactData::RegionSizeOffsetMask = RegionSize - 1; |
36 const size_t ParallelCompactData::RegionAddrOffsetMask = RegionSizeBytes - 1; | 36 const size_t ParallelCompactData::RegionAddrOffsetMask = RegionSizeBytes - 1; |
37 const size_t ParallelCompactData::RegionAddrMask = ~RegionAddrOffsetMask; | 37 const size_t ParallelCompactData::RegionAddrMask = ~RegionAddrOffsetMask; |
38 | 38 |
39 // 32-bit: 128 words covers 4 bitmap words | |
40 // 64-bit: 128 words covers 2 bitmap words | |
41 const size_t ParallelCompactData::Log2BlockSize = 7; // 128 words | |
42 const size_t ParallelCompactData::BlockSize = (size_t)1 << Log2BlockSize; | |
43 const size_t ParallelCompactData::BlockOffsetMask = BlockSize - 1; | |
44 const size_t ParallelCompactData::BlockMask = ~BlockOffsetMask; | |
45 | |
46 const size_t ParallelCompactData::BlocksPerRegion = RegionSize / BlockSize; | |
47 | |
48 const ParallelCompactData::RegionData::region_sz_t | 39 const ParallelCompactData::RegionData::region_sz_t |
49 ParallelCompactData::RegionData::dc_shift = 27; | 40 ParallelCompactData::RegionData::dc_shift = 27; |
50 | 41 |
51 const ParallelCompactData::RegionData::region_sz_t | 42 const ParallelCompactData::RegionData::region_sz_t |
52 ParallelCompactData::RegionData::dc_mask = ~0U << dc_shift; | 43 ParallelCompactData::RegionData::dc_mask = ~0U << dc_shift; |
60 const ParallelCompactData::RegionData::region_sz_t | 51 const ParallelCompactData::RegionData::region_sz_t |
61 ParallelCompactData::RegionData::dc_claimed = 0x8U << dc_shift; | 52 ParallelCompactData::RegionData::dc_claimed = 0x8U << dc_shift; |
62 | 53 |
63 const ParallelCompactData::RegionData::region_sz_t | 54 const ParallelCompactData::RegionData::region_sz_t |
64 ParallelCompactData::RegionData::dc_completed = 0xcU << dc_shift; | 55 ParallelCompactData::RegionData::dc_completed = 0xcU << dc_shift; |
65 | |
66 #ifdef ASSERT | |
67 short ParallelCompactData::BlockData::_cur_phase = 0; | |
68 #endif | |
69 | 56 |
70 SpaceInfo PSParallelCompact::_space_info[PSParallelCompact::last_space_id]; | 57 SpaceInfo PSParallelCompact::_space_info[PSParallelCompact::last_space_id]; |
71 bool PSParallelCompact::_print_phases = false; | 58 bool PSParallelCompact::_print_phases = false; |
72 | 59 |
73 ReferenceProcessor* PSParallelCompact::_ref_processor = NULL; | 60 ReferenceProcessor* PSParallelCompact::_ref_processor = NULL; |
288 _region_start = 0; | 275 _region_start = 0; |
289 | 276 |
290 _region_vspace = 0; | 277 _region_vspace = 0; |
291 _region_data = 0; | 278 _region_data = 0; |
292 _region_count = 0; | 279 _region_count = 0; |
293 | |
294 _block_vspace = 0; | |
295 _block_data = 0; | |
296 _block_count = 0; | |
297 } | 280 } |
298 | 281 |
299 bool ParallelCompactData::initialize(MemRegion covered_region) | 282 bool ParallelCompactData::initialize(MemRegion covered_region) |
300 { | 283 { |
301 _region_start = covered_region.start(); | 284 _region_start = covered_region.start(); |
306 "region start not aligned"); | 289 "region start not aligned"); |
307 assert((region_size & RegionSizeOffsetMask) == 0, | 290 assert((region_size & RegionSizeOffsetMask) == 0, |
308 "region size not a multiple of RegionSize"); | 291 "region size not a multiple of RegionSize"); |
309 | 292 |
310 bool result = initialize_region_data(region_size); | 293 bool result = initialize_region_data(region_size); |
311 | |
312 // Initialize the block data if it will be used for updating pointers, or if | |
313 // this is a debug build. | |
314 if (!UseParallelOldGCRegionPointerCalc || trueInDebug) { | |
315 result = result && initialize_block_data(region_size); | |
316 } | |
317 | 294 |
318 return result; | 295 return result; |
319 } | 296 } |
320 | 297 |
321 PSVirtualSpace* | 298 PSVirtualSpace* |
354 return true; | 331 return true; |
355 } | 332 } |
356 return false; | 333 return false; |
357 } | 334 } |
358 | 335 |
359 bool ParallelCompactData::initialize_block_data(size_t region_size) | |
360 { | |
361 const size_t count = (region_size + BlockOffsetMask) >> Log2BlockSize; | |
362 _block_vspace = create_vspace(count, sizeof(BlockData)); | |
363 if (_block_vspace != 0) { | |
364 _block_data = (BlockData*)_block_vspace->reserved_low_addr(); | |
365 _block_count = count; | |
366 return true; | |
367 } | |
368 return false; | |
369 } | |
370 | |
371 void ParallelCompactData::clear() | 336 void ParallelCompactData::clear() |
372 { | 337 { |
373 if (_block_data) { | |
374 memset(_block_data, 0, _block_vspace->committed_size()); | |
375 } | |
376 memset(_region_data, 0, _region_vspace->committed_size()); | 338 memset(_region_data, 0, _region_vspace->committed_size()); |
377 } | 339 } |
378 | 340 |
379 void ParallelCompactData::clear_range(size_t beg_region, size_t end_region) { | 341 void ParallelCompactData::clear_range(size_t beg_region, size_t end_region) { |
380 assert(beg_region <= _region_count, "beg_region out of range"); | 342 assert(beg_region <= _region_count, "beg_region out of range"); |
381 assert(end_region <= _region_count, "end_region out of range"); | 343 assert(end_region <= _region_count, "end_region out of range"); |
382 assert(RegionSize % BlockSize == 0, "RegionSize not a multiple of BlockSize"); | |
383 | 344 |
384 const size_t region_cnt = end_region - beg_region; | 345 const size_t region_cnt = end_region - beg_region; |
385 | |
386 if (_block_data) { | |
387 const size_t blocks_per_region = RegionSize / BlockSize; | |
388 const size_t beg_block = beg_region * blocks_per_region; | |
389 const size_t block_cnt = region_cnt * blocks_per_region; | |
390 memset(_block_data + beg_block, 0, block_cnt * sizeof(BlockData)); | |
391 } | |
392 memset(_region_data + beg_region, 0, region_cnt * sizeof(RegionData)); | 346 memset(_region_data + beg_region, 0, region_cnt * sizeof(RegionData)); |
393 } | 347 } |
394 | 348 |
395 HeapWord* ParallelCompactData::partial_obj_end(size_t region_idx) const | 349 HeapWord* ParallelCompactData::partial_obj_end(size_t region_idx) const |
396 { | 350 { |
563 | 517 |
564 *target_next = dest_addr; | 518 *target_next = dest_addr; |
565 return true; | 519 return true; |
566 } | 520 } |
567 | 521 |
568 bool ParallelCompactData::partial_obj_ends_in_block(size_t block_index) { | |
569 HeapWord* block_addr = block_to_addr(block_index); | |
570 HeapWord* block_end_addr = block_addr + BlockSize; | |
571 size_t region_index = addr_to_region_idx(block_addr); | |
572 HeapWord* partial_obj_end_addr = partial_obj_end(region_index); | |
573 | |
574 // An object that ends at the end of the block, ends | |
575 // in the block (the last word of the object is to | |
576 // the left of the end). | |
577 if ((block_addr < partial_obj_end_addr) && | |
578 (partial_obj_end_addr <= block_end_addr)) { | |
579 return true; | |
580 } | |
581 | |
582 return false; | |
583 } | |
584 | |
585 HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) { | 522 HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) { |
586 HeapWord* result = NULL; | |
587 if (UseParallelOldGCRegionPointerCalc) { | |
588 result = region_calc_new_pointer(addr); | |
589 } else { | |
590 result = block_calc_new_pointer(addr); | |
591 } | |
592 return result; | |
593 } | |
594 | |
595 // This method is overly complicated (expensive) to be called | |
596 // for every reference. | |
597 // Try to restructure this so that a NULL is returned if | |
598 // the object is dead. But don't wast the cycles to explicitly check | |
599 // that it is dead since only live objects should be passed in. | |
600 | |
601 HeapWord* ParallelCompactData::region_calc_new_pointer(HeapWord* addr) { | |
602 assert(addr != NULL, "Should detect NULL oop earlier"); | 523 assert(addr != NULL, "Should detect NULL oop earlier"); |
603 assert(PSParallelCompact::gc_heap()->is_in(addr), "addr not in heap"); | 524 assert(PSParallelCompact::gc_heap()->is_in(addr), "addr not in heap"); |
604 #ifdef ASSERT | 525 #ifdef ASSERT |
605 if (PSParallelCompact::mark_bitmap()->is_unmarked(addr)) { | 526 if (PSParallelCompact::mark_bitmap()->is_unmarked(addr)) { |
606 gclog_or_tty->print_cr("calc_new_pointer:: addr " PTR_FORMAT, addr); | 527 gclog_or_tty->print_cr("calc_new_pointer:: addr " PTR_FORMAT, addr); |
639 result += partial_obj_size + live_to_left; | 560 result += partial_obj_size + live_to_left; |
640 assert(result <= addr, "object cannot move to the right"); | 561 assert(result <= addr, "object cannot move to the right"); |
641 return result; | 562 return result; |
642 } | 563 } |
643 | 564 |
644 HeapWord* ParallelCompactData::block_calc_new_pointer(HeapWord* addr) { | |
645 assert(addr != NULL, "Should detect NULL oop earlier"); | |
646 assert(PSParallelCompact::gc_heap()->is_in(addr), "addr not in heap"); | |
647 #ifdef ASSERT | |
648 if (PSParallelCompact::mark_bitmap()->is_unmarked(addr)) { | |
649 gclog_or_tty->print_cr("calc_new_pointer:: addr " PTR_FORMAT, addr); | |
650 } | |
651 #endif | |
652 assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "obj not marked"); | |
653 | |
654 // Region covering the object. | |
655 size_t region_index = addr_to_region_idx(addr); | |
656 const RegionData* const region_ptr = region(region_index); | |
657 HeapWord* const region_addr = region_align_down(addr); | |
658 | |
659 assert(addr < region_addr + RegionSize, "Region does not cover object"); | |
660 assert(addr_to_region_ptr(region_addr) == region_ptr, "sanity check"); | |
661 | |
662 HeapWord* result = region_ptr->destination(); | |
663 | |
664 // If all the data in the region is live, then the new location of the object | |
665 // can be calculated from the destination of the region plus the offset of the | |
666 // object in the region. | |
667 if (region_ptr->data_size() == RegionSize) { | |
668 result += pointer_delta(addr, region_addr); | |
669 return result; | |
670 } | |
671 | |
672 // The new location of the object is | |
673 // region destination + | |
674 // block offset + | |
675 // sizes of the live objects in the Block that are to the left of addr | |
676 const size_t block_offset = addr_to_block_ptr(addr)->offset(); | |
677 HeapWord* const search_start = region_addr + block_offset; | |
678 | |
679 const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap(); | |
680 size_t live_to_left = bitmap->live_words_in_range(search_start, oop(addr)); | |
681 | |
682 result += block_offset + live_to_left; | |
683 assert(result <= addr, "object cannot move to the right"); | |
684 assert(result == region_calc_new_pointer(addr), "Should match"); | |
685 return result; | |
686 } | |
687 | |
688 klassOop ParallelCompactData::calc_new_klass(klassOop old_klass) { | 565 klassOop ParallelCompactData::calc_new_klass(klassOop old_klass) { |
689 klassOop updated_klass; | 566 klassOop updated_klass; |
690 if (PSParallelCompact::should_update_klass(old_klass)) { | 567 if (PSParallelCompact::should_update_klass(old_klass)) { |
691 updated_klass = (klassOop) calc_new_pointer(old_klass); | 568 updated_klass = (klassOop) calc_new_pointer(old_klass); |
692 } else { | 569 } else { |
707 } | 584 } |
708 | 585 |
709 void ParallelCompactData::verify_clear() | 586 void ParallelCompactData::verify_clear() |
710 { | 587 { |
711 verify_clear(_region_vspace); | 588 verify_clear(_region_vspace); |
712 verify_clear(_block_vspace); | |
713 } | 589 } |
714 #endif // #ifdef ASSERT | 590 #endif // #ifdef ASSERT |
715 | 591 |
716 #ifdef NOT_PRODUCT | 592 #ifdef NOT_PRODUCT |
717 ParallelCompactData::RegionData* debug_region(size_t region_index) { | 593 ParallelCompactData::RegionData* debug_region(size_t region_index) { |
1579 // Reset the new_top value for the space. | 1455 // Reset the new_top value for the space. |
1580 _space_info[id].set_new_top(space->bottom()); | 1456 _space_info[id].set_new_top(space->bottom()); |
1581 } | 1457 } |
1582 } | 1458 } |
1583 | 1459 |
1584 // Fill in the block data after any changes to the regions have | |
1585 // been made. | |
1586 #ifdef ASSERT | |
1587 summarize_blocks(cm, perm_space_id); | |
1588 summarize_blocks(cm, old_space_id); | |
1589 #else | |
1590 if (!UseParallelOldGCRegionPointerCalc) { | |
1591 summarize_blocks(cm, perm_space_id); | |
1592 summarize_blocks(cm, old_space_id); | |
1593 } | |
1594 #endif | |
1595 | |
1596 if (TraceParallelOldGCSummaryPhase) { | 1460 if (TraceParallelOldGCSummaryPhase) { |
1597 tty->print_cr("summary_phase: after final summarization"); | 1461 tty->print_cr("summary_phase: after final summarization"); |
1598 Universe::print(); | 1462 Universe::print(); |
1599 NOT_PRODUCT(print_region_ranges()); | 1463 NOT_PRODUCT(print_region_ranges()); |
1600 if (Verbose) { | 1464 if (Verbose) { |
1601 NOT_PRODUCT(print_generic_summary_data(_summary_data, _space_info)); | 1465 NOT_PRODUCT(print_generic_summary_data(_summary_data, _space_info)); |
1602 } | 1466 } |
1603 } | 1467 } |
1604 } | |
1605 | |
1606 // Fill in the BlockData. | |
1607 // Iterate over the spaces and within each space iterate over | |
1608 // the regions and fill in the BlockData for each region. | |
1609 | |
1610 void PSParallelCompact::summarize_blocks(ParCompactionManager* cm, | |
1611 SpaceId first_compaction_space_id) { | |
1612 #if 0 | |
1613 DEBUG_ONLY(ParallelCompactData::BlockData::set_cur_phase(1);) | |
1614 for (SpaceId cur_space_id = first_compaction_space_id; | |
1615 cur_space_id != last_space_id; | |
1616 cur_space_id = next_compaction_space_id(cur_space_id)) { | |
1617 // Iterate over the regions in the space | |
1618 size_t start_region_index = | |
1619 _summary_data.addr_to_region_idx(space(cur_space_id)->bottom()); | |
1620 BitBlockUpdateClosure bbu(mark_bitmap(), | |
1621 cm, | |
1622 start_region_index); | |
1623 // Iterate over blocks. | |
1624 for (size_t region_index = start_region_index; | |
1625 region_index < _summary_data.region_count() && | |
1626 _summary_data.region_to_addr(region_index) < | |
1627 space(cur_space_id)->top(); | |
1628 region_index++) { | |
1629 | |
1630 // Reset the closure for the new region. Note that the closure | |
1631 // maintains some data that does not get reset for each region | |
1632 // so a new instance of the closure is no appropriate. | |
1633 bbu.reset_region(region_index); | |
1634 | |
1635 // Start the iteration with the first live object. This | |
1636 // may return the end of the region. That is acceptable since | |
1637 // it will properly limit the iterations. | |
1638 ParMarkBitMap::idx_t left_offset = mark_bitmap()->addr_to_bit( | |
1639 _summary_data.first_live_or_end_in_region(region_index)); | |
1640 | |
1641 // End the iteration at the end of the region. | |
1642 HeapWord* region_addr = _summary_data.region_to_addr(region_index); | |
1643 HeapWord* region_end = region_addr + ParallelCompactData::RegionSize; | |
1644 ParMarkBitMap::idx_t right_offset = | |
1645 mark_bitmap()->addr_to_bit(region_end); | |
1646 | |
1647 // Blocks that have not objects starting in them can be | |
1648 // skipped because their data will never be used. | |
1649 if (left_offset < right_offset) { | |
1650 | |
1651 // Iterate through the objects in the region. | |
1652 ParMarkBitMap::idx_t last_offset = | |
1653 mark_bitmap()->pair_iterate(&bbu, left_offset, right_offset); | |
1654 | |
1655 // If last_offset is less than right_offset, then the iterations | |
1656 // terminated while it was looking for an end bit. "last_offset" | |
1657 // is then the offset for the last start bit. In this situation | |
1658 // the "offset" field for the next block to the right (_cur_block + 1) | |
1659 // will not have been update although there may be live data | |
1660 // to the left of the region. | |
1661 | |
1662 size_t cur_block_plus_1 = bbu.cur_block() + 1; | |
1663 HeapWord* cur_block_plus_1_addr = | |
1664 _summary_data.block_to_addr(bbu.cur_block()) + | |
1665 ParallelCompactData::BlockSize; | |
1666 HeapWord* last_offset_addr = mark_bitmap()->bit_to_addr(last_offset); | |
1667 #if 1 // This code works. The else doesn't but should. Why does it? | |
1668 // The current block (cur_block()) has already been updated. | |
1669 // The last block that may need to be updated is either the | |
1670 // next block (current block + 1) or the block where the | |
1671 // last object starts (which can be greater than the | |
1672 // next block if there were no objects found in intervening | |
1673 // blocks). | |
1674 size_t last_block = | |
1675 MAX2(bbu.cur_block() + 1, | |
1676 _summary_data.addr_to_block_idx(last_offset_addr)); | |
1677 #else | |
1678 // The current block has already been updated. The only block | |
1679 // that remains to be updated is the block where the last | |
1680 // object in the region starts. | |
1681 size_t last_block = _summary_data.addr_to_block_idx(last_offset_addr); | |
1682 #endif | |
1683 assert_bit_is_start(last_offset); | |
1684 assert((last_block == _summary_data.block_count()) || | |
1685 (_summary_data.block(last_block)->raw_offset() == 0), | |
1686 "Should not have been set"); | |
1687 // Is the last block still in the current region? If still | |
1688 // in this region, update the last block (the counting that | |
1689 // included the current block is meant for the offset of the last | |
1690 // block). If not in this region, do nothing. Should not | |
1691 // update a block in the next region. | |
1692 if (ParallelCompactData::region_contains_block(bbu.region_index(), | |
1693 last_block)) { | |
1694 if (last_offset < right_offset) { | |
1695 // The last object started in this region but ends beyond | |
1696 // this region. Update the block for this last object. | |
1697 assert(mark_bitmap()->is_marked(last_offset), "Should be marked"); | |
1698 // No end bit was found. The closure takes care of | |
1699 // the cases where | |
1700 // an objects crosses over into the next block | |
1701 // an objects starts and ends in the next block | |
1702 // It does not handle the case where an object is | |
1703 // the first object in a later block and extends | |
1704 // past the end of the region (i.e., the closure | |
1705 // only handles complete objects that are in the range | |
1706 // it is given). That object is handed back here | |
1707 // for any special consideration necessary. | |
1708 // | |
1709 // Is the first bit in the last block a start or end bit? | |
1710 // | |
1711 // If the partial object ends in the last block L, | |
1712 // then the 1st bit in L may be an end bit. | |
1713 // | |
1714 // Else does the last object start in a block after the current | |
1715 // block? A block AA will already have been updated if an | |
1716 // object ends in the next block AA+1. An object found to end in | |
1717 // the AA+1 is the trigger that updates AA. Objects are being | |
1718 // counted in the current block for updaing a following | |
1719 // block. An object may start in later block | |
1720 // block but may extend beyond the last block in the region. | |
1721 // Updates are only done when the end of an object has been | |
1722 // found. If the last object (covered by block L) starts | |
1723 // beyond the current block, then no object ends in L (otherwise | |
1724 // L would be the current block). So the first bit in L is | |
1725 // a start bit. | |
1726 // | |
1727 // Else the last objects start in the current block and ends | |
1728 // beyond the region. The current block has already been | |
1729 // updated and there is no later block (with an object | |
1730 // starting in it) that needs to be updated. | |
1731 // | |
1732 if (_summary_data.partial_obj_ends_in_block(last_block)) { | |
1733 _summary_data.block(last_block)->set_end_bit_offset( | |
1734 bbu.live_data_left()); | |
1735 } else if (last_offset_addr >= cur_block_plus_1_addr) { | |
1736 // The start of the object is on a later block | |
1737 // (to the right of the current block and there are no | |
1738 // complete live objects to the left of this last object | |
1739 // within the region. | |
1740 // The first bit in the block is for the start of the | |
1741 // last object. | |
1742 _summary_data.block(last_block)->set_start_bit_offset( | |
1743 bbu.live_data_left()); | |
1744 } else { | |
1745 // The start of the last object was found in | |
1746 // the current region (which has already | |
1747 // been updated). | |
1748 assert(bbu.cur_block() == | |
1749 _summary_data.addr_to_block_idx(last_offset_addr), | |
1750 "Should be a block already processed"); | |
1751 } | |
1752 #ifdef ASSERT | |
1753 // Is there enough block information to find this object? | |
1754 // The destination of the region has not been set so the | |
1755 // values returned by calc_new_pointer() and | |
1756 // block_calc_new_pointer() will only be | |
1757 // offsets. But they should agree. | |
1758 HeapWord* moved_obj_with_regions = | |
1759 _summary_data.region_calc_new_pointer(last_offset_addr); | |
1760 HeapWord* moved_obj_with_blocks = | |
1761 _summary_data.calc_new_pointer(last_offset_addr); | |
1762 assert(moved_obj_with_regions == moved_obj_with_blocks, | |
1763 "Block calculation is wrong"); | |
1764 #endif | |
1765 } else if (last_block < _summary_data.block_count()) { | |
1766 // Iterations ended looking for a start bit (but | |
1767 // did not run off the end of the block table). | |
1768 _summary_data.block(last_block)->set_start_bit_offset( | |
1769 bbu.live_data_left()); | |
1770 } | |
1771 } | |
1772 #ifdef ASSERT | |
1773 // Is there enough block information to find this object? | |
1774 HeapWord* left_offset_addr = mark_bitmap()->bit_to_addr(left_offset); | |
1775 HeapWord* moved_obj_with_regions = | |
1776 _summary_data.calc_new_pointer(left_offset_addr); | |
1777 HeapWord* moved_obj_with_blocks = | |
1778 _summary_data.calc_new_pointer(left_offset_addr); | |
1779 assert(moved_obj_with_regions == moved_obj_with_blocks, | |
1780 "Block calculation is wrong"); | |
1781 #endif | |
1782 | |
1783 // Is there another block after the end of this region? | |
1784 #ifdef ASSERT | |
1785 if (last_block < _summary_data.block_count()) { | |
1786 // No object may have been found in a block. If that | |
1787 // block is at the end of the region, the iteration will | |
1788 // terminate without incrementing the current block so | |
1789 // that the current block is not the last block in the | |
1790 // region. That situation precludes asserting that the | |
1791 // current block is the last block in the region. Assert | |
1792 // the lesser condition that the current block does not | |
1793 // exceed the region. | |
1794 assert(_summary_data.block_to_addr(last_block) <= | |
1795 (_summary_data.region_to_addr(region_index) + | |
1796 ParallelCompactData::RegionSize), | |
1797 "Region and block inconsistency"); | |
1798 assert(last_offset <= right_offset, "Iteration over ran end"); | |
1799 } | |
1800 #endif | |
1801 } | |
1802 #ifdef ASSERT | |
1803 if (PrintGCDetails && Verbose) { | |
1804 if (_summary_data.region(region_index)->partial_obj_size() == 1) { | |
1805 size_t first_block = | |
1806 region_index / ParallelCompactData::BlocksPerRegion; | |
1807 gclog_or_tty->print_cr("first_block " PTR_FORMAT | |
1808 " _offset " PTR_FORMAT | |
1809 "_first_is_start_bit %d", | |
1810 first_block, | |
1811 _summary_data.block(first_block)->raw_offset(), | |
1812 _summary_data.block(first_block)->first_is_start_bit()); | |
1813 } | |
1814 } | |
1815 #endif | |
1816 } | |
1817 } | |
1818 DEBUG_ONLY(ParallelCompactData::BlockData::set_cur_phase(16);) | |
1819 #endif // #if 0 | |
1820 } | 1468 } |
1821 | 1469 |
1822 // This method should contain all heap-specific policy for invoking a full | 1470 // This method should contain all heap-specific policy for invoking a full |
1823 // collection. invoke_no_policy() will only attempt to compact the heap; it | 1471 // collection. invoke_no_policy() will only attempt to compact the heap; it |
1824 // will do nothing further. If we need to bail out for policy reasons, scavenge | 1472 // will do nothing further. If we need to bail out for policy reasons, scavenge |
1854 } | 1502 } |
1855 | 1503 |
1856 bool ParallelCompactData::region_contains(size_t region_index, HeapWord* addr) { | 1504 bool ParallelCompactData::region_contains(size_t region_index, HeapWord* addr) { |
1857 size_t addr_region_index = addr_to_region_idx(addr); | 1505 size_t addr_region_index = addr_to_region_idx(addr); |
1858 return region_index == addr_region_index; | 1506 return region_index == addr_region_index; |
1859 } | |
1860 | |
1861 bool ParallelCompactData::region_contains_block(size_t region_index, | |
1862 size_t block_index) { | |
1863 size_t first_block_in_region = region_index * BlocksPerRegion; | |
1864 size_t last_block_in_region = (region_index + 1) * BlocksPerRegion - 1; | |
1865 | |
1866 return (first_block_in_region <= block_index) && | |
1867 (block_index <= last_block_in_region); | |
1868 } | 1507 } |
1869 | 1508 |
1870 // This method contains no policy. You should probably | 1509 // This method contains no policy. You should probably |
1871 // be calling invoke() instead. | 1510 // be calling invoke() instead. |
1872 void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { | 1511 void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { |
3337 UpdateOnlyClosure::do_addr(HeapWord* addr, size_t words) { | 2976 UpdateOnlyClosure::do_addr(HeapWord* addr, size_t words) { |
3338 do_addr(addr); | 2977 do_addr(addr); |
3339 return ParMarkBitMap::incomplete; | 2978 return ParMarkBitMap::incomplete; |
3340 } | 2979 } |
3341 | 2980 |
3342 BitBlockUpdateClosure::BitBlockUpdateClosure(ParMarkBitMap* mbm, | |
3343 ParCompactionManager* cm, | |
3344 size_t region_index) : | |
3345 ParMarkBitMapClosure(mbm, cm), | |
3346 _live_data_left(0), | |
3347 _cur_block(0) { | |
3348 _region_start = | |
3349 PSParallelCompact::summary_data().region_to_addr(region_index); | |
3350 _region_end = | |
3351 PSParallelCompact::summary_data().region_to_addr(region_index) + | |
3352 ParallelCompactData::RegionSize; | |
3353 _region_index = region_index; | |
3354 _cur_block = | |
3355 PSParallelCompact::summary_data().addr_to_block_idx(_region_start); | |
3356 } | |
3357 | |
3358 bool BitBlockUpdateClosure::region_contains_cur_block() { | |
3359 return ParallelCompactData::region_contains_block(_region_index, _cur_block); | |
3360 } | |
3361 | |
3362 void BitBlockUpdateClosure::reset_region(size_t region_index) { | |
3363 DEBUG_ONLY(ParallelCompactData::BlockData::set_cur_phase(7);) | |
3364 ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
3365 _region_index = region_index; | |
3366 _live_data_left = 0; | |
3367 _region_start = sd.region_to_addr(region_index); | |
3368 _region_end = sd.region_to_addr(region_index) + ParallelCompactData::RegionSize; | |
3369 | |
3370 // The first block in this region | |
3371 size_t first_block = sd.addr_to_block_idx(_region_start); | |
3372 size_t partial_live_size = sd.region(region_index)->partial_obj_size(); | |
3373 | |
3374 // Set the offset to 0. By definition it should have that value | |
3375 // but it may have been written while processing an earlier region. | |
3376 if (partial_live_size == 0) { | |
3377 // No live object extends onto the region. The first bit | |
3378 // in the bit map for the first region must be a start bit. | |
3379 // Although there may not be any marked bits, it is safe | |
3380 // to set it as a start bit. | |
3381 sd.block(first_block)->set_start_bit_offset(0); | |
3382 sd.block(first_block)->set_first_is_start_bit(true); | |
3383 } else if (sd.partial_obj_ends_in_block(first_block)) { | |
3384 sd.block(first_block)->set_end_bit_offset(0); | |
3385 sd.block(first_block)->set_first_is_start_bit(false); | |
3386 } else { | |
3387 // The partial object extends beyond the first block. | |
3388 // There is no object starting in the first block | |
3389 // so the offset and bit parity are not needed. | |
3390 // Set the the bit parity to start bit so assertions | |
3391 // work when not bit is found. | |
3392 sd.block(first_block)->set_end_bit_offset(0); | |
3393 sd.block(first_block)->set_first_is_start_bit(false); | |
3394 } | |
3395 _cur_block = first_block; | |
3396 #ifdef ASSERT | |
3397 if (sd.block(first_block)->first_is_start_bit()) { | |
3398 assert(!sd.partial_obj_ends_in_block(first_block), | |
3399 "Partial object cannot end in first block"); | |
3400 } | |
3401 | |
3402 if (PrintGCDetails && Verbose) { | |
3403 if (partial_live_size == 1) { | |
3404 gclog_or_tty->print_cr("first_block " PTR_FORMAT | |
3405 " _offset " PTR_FORMAT | |
3406 " _first_is_start_bit %d", | |
3407 first_block, | |
3408 sd.block(first_block)->raw_offset(), | |
3409 sd.block(first_block)->first_is_start_bit()); | |
3410 } | |
3411 } | |
3412 #endif | |
3413 DEBUG_ONLY(ParallelCompactData::BlockData::set_cur_phase(17);) | |
3414 } | |
3415 | |
3416 // This method is called when a object has been found (both beginning | |
3417 // and end of the object) in the range of iteration. This method is | |
3418 // calculating the words of live data to the left of a block. That live | |
3419 // data includes any object starting to the left of the block (i.e., | |
3420 // the live-data-to-the-left of block AAA will include the full size | |
3421 // of any object entering AAA). | |
3422 | |
3423 ParMarkBitMapClosure::IterationStatus | |
3424 BitBlockUpdateClosure::do_addr(HeapWord* addr, size_t words) { | |
3425 // add the size to the block data. | |
3426 HeapWord* obj = addr; | |
3427 ParallelCompactData& sd = PSParallelCompact::summary_data(); | |
3428 | |
3429 assert(bitmap()->obj_size(obj) == words, "bad size"); | |
3430 assert(_region_start <= obj, "object is not in region"); | |
3431 assert(obj + words <= _region_end, "object is not in region"); | |
3432 | |
3433 // Update the live data to the left | |
3434 size_t prev_live_data_left = _live_data_left; | |
3435 _live_data_left = _live_data_left + words; | |
3436 | |
3437 // Is this object in the current block. | |
3438 size_t block_of_obj = sd.addr_to_block_idx(obj); | |
3439 size_t block_of_obj_last = sd.addr_to_block_idx(obj + words - 1); | |
3440 HeapWord* block_of_obj_last_addr = sd.block_to_addr(block_of_obj_last); | |
3441 if (_cur_block < block_of_obj) { | |
3442 | |
3443 // | |
3444 // No object crossed the block boundary and this object was found | |
3445 // on the other side of the block boundary. Update the offset for | |
3446 // the new block with the data size that does not include this object. | |
3447 // | |
3448 // The first bit in block_of_obj is a start bit except in the | |
3449 // case where the partial object for the region extends into | |
3450 // this block. | |
3451 if (sd.partial_obj_ends_in_block(block_of_obj)) { | |
3452 sd.block(block_of_obj)->set_end_bit_offset(prev_live_data_left); | |
3453 } else { | |
3454 sd.block(block_of_obj)->set_start_bit_offset(prev_live_data_left); | |
3455 } | |
3456 | |
3457 // Does this object pass beyond the its block? | |
3458 if (block_of_obj < block_of_obj_last) { | |
3459 // Object crosses block boundary. Two blocks need to be udpated: | |
3460 // the current block where the object started | |
3461 // the block where the object ends | |
3462 // | |
3463 // The offset for blocks with no objects starting in them | |
3464 // (e.g., blocks between _cur_block and block_of_obj_last) | |
3465 // should not be needed. | |
3466 // Note that block_of_obj_last may be in another region. If so, | |
3467 // it should be overwritten later. This is a problem (writting | |
3468 // into a block in a later region) for parallel execution. | |
3469 assert(obj < block_of_obj_last_addr, | |
3470 "Object should start in previous block"); | |
3471 | |
3472 // obj is crossing into block_of_obj_last so the first bit | |
3473 // is and end bit. | |
3474 sd.block(block_of_obj_last)->set_end_bit_offset(_live_data_left); | |
3475 | |
3476 _cur_block = block_of_obj_last; | |
3477 } else { | |
3478 // _first_is_start_bit has already been set correctly | |
3479 // in the if-then-else above so don't reset it here. | |
3480 _cur_block = block_of_obj; | |
3481 } | |
3482 } else { | |
3483 // The current block only changes if the object extends beyound | |
3484 // the block it starts in. | |
3485 // | |
3486 // The object starts in the current block. | |
3487 // Does this object pass beyond the end of it? | |
3488 if (block_of_obj < block_of_obj_last) { | |
3489 // Object crosses block boundary. | |
3490 // See note above on possible blocks between block_of_obj and | |
3491 // block_of_obj_last | |
3492 assert(obj < block_of_obj_last_addr, | |
3493 "Object should start in previous block"); | |
3494 | |
3495 sd.block(block_of_obj_last)->set_end_bit_offset(_live_data_left); | |
3496 | |
3497 _cur_block = block_of_obj_last; | |
3498 } | |
3499 } | |
3500 | |
3501 // Return incomplete if there are more blocks to be done. | |
3502 if (region_contains_cur_block()) { | |
3503 return ParMarkBitMap::incomplete; | |
3504 } | |
3505 return ParMarkBitMap::complete; | |
3506 } | |
3507 | |
3508 // Verify the new location using the forwarding pointer | 2981 // Verify the new location using the forwarding pointer |
3509 // from MarkSweep::mark_sweep_phase2(). Set the mark_word | 2982 // from MarkSweep::mark_sweep_phase2(). Set the mark_word |
3510 // to the initial value. | 2983 // to the initial value. |
3511 ParMarkBitMapClosure::IterationStatus | 2984 ParMarkBitMapClosure::IterationStatus |
3512 PSParallelCompact::VerifyUpdateClosure::do_addr(HeapWord* addr, size_t words) { | 2985 PSParallelCompact::VerifyUpdateClosure::do_addr(HeapWord* addr, size_t words) { |
3575 default: | 3048 default: |
3576 assert(false, "Bad space id"); | 3049 assert(false, "Bad space id"); |
3577 return last_space_id; | 3050 return last_space_id; |
3578 } | 3051 } |
3579 } | 3052 } |
3580 | |
3581 // Here temporarily for debugging | |
3582 #ifdef ASSERT | |
3583 size_t ParallelCompactData::block_idx(BlockData* block) { | |
3584 size_t index = pointer_delta(block, | |
3585 PSParallelCompact::summary_data()._block_data, sizeof(BlockData)); | |
3586 return index; | |
3587 } | |
3588 #endif |