1 /* |
1 /* |
2 * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
564 } |
564 } |
565 } |
565 } |
566 #endif |
566 #endif |
567 |
567 |
568 // Commit new or uncommit old pages, if necessary. |
568 // Commit new or uncommit old pages, if necessary. |
569 resize_commit_uncommit(changed_region, new_region); |
569 if (resize_commit_uncommit(changed_region, new_region)) { |
|
570 // Set the new start of the committed region |
|
571 resize_update_committed_table(changed_region, new_region); |
|
572 } |
570 |
573 |
571 // Update card table entries |
574 // Update card table entries |
572 resize_update_card_table_entries(changed_region, new_region); |
575 resize_update_card_table_entries(changed_region, new_region); |
573 |
|
574 // Set the new start of the committed region |
|
575 resize_update_committed_table(changed_region, new_region); |
|
576 |
576 |
577 // Update the covered region |
577 // Update the covered region |
578 resize_update_covered_table(changed_region, new_region); |
578 resize_update_covered_table(changed_region, new_region); |
579 |
579 |
580 if (TraceCardTableModRefBS) { |
580 if (TraceCardTableModRefBS) { |
602 addr_for((jbyte*) _committed[ind].last())); |
602 addr_for((jbyte*) _committed[ind].last())); |
603 } |
603 } |
604 debug_only(verify_guard();) |
604 debug_only(verify_guard();) |
605 } |
605 } |
606 |
606 |
607 void CardTableExtension::resize_commit_uncommit(int changed_region, |
607 bool CardTableExtension::resize_commit_uncommit(int changed_region, |
608 MemRegion new_region) { |
608 MemRegion new_region) { |
|
609 bool result = false; |
609 // Commit new or uncommit old pages, if necessary. |
610 // Commit new or uncommit old pages, if necessary. |
610 MemRegion cur_committed = _committed[changed_region]; |
611 MemRegion cur_committed = _committed[changed_region]; |
611 assert(_covered[changed_region].end() == new_region.end(), |
612 assert(_covered[changed_region].end() == new_region.end(), |
612 "The ends of the regions are expected to match"); |
613 "The ends of the regions are expected to match"); |
613 // Extend the start of this _committed region to |
614 // Extend the start of this _committed region to |
673 new_committed.byte_size())) { |
674 new_committed.byte_size())) { |
674 vm_exit_out_of_memory(new_committed.byte_size(), |
675 vm_exit_out_of_memory(new_committed.byte_size(), |
675 "card table expansion"); |
676 "card table expansion"); |
676 } |
677 } |
677 } |
678 } |
|
679 result = true; |
678 } else if (new_start_aligned > cur_committed.start()) { |
680 } else if (new_start_aligned > cur_committed.start()) { |
679 // Shrink the committed region |
681 // Shrink the committed region |
|
682 #if 0 // uncommitting space is currently unsafe because of the interactions |
|
683 // of growing and shrinking regions. One region A can uncommit space |
|
684 // that it owns but which is being used by another region B (maybe). |
|
685 // Region B has not committed the space because it was already |
|
686 // committed by region A. |
680 MemRegion uncommit_region = committed_unique_to_self(changed_region, |
687 MemRegion uncommit_region = committed_unique_to_self(changed_region, |
681 MemRegion(cur_committed.start(), new_start_aligned)); |
688 MemRegion(cur_committed.start(), new_start_aligned)); |
682 if (!uncommit_region.is_empty()) { |
689 if (!uncommit_region.is_empty()) { |
683 if (!os::uncommit_memory((char*)uncommit_region.start(), |
690 if (!os::uncommit_memory((char*)uncommit_region.start(), |
684 uncommit_region.byte_size())) { |
691 uncommit_region.byte_size())) { |
685 vm_exit_out_of_memory(uncommit_region.byte_size(), |
692 // If the uncommit fails, ignore it. Let the |
686 "card table contraction"); |
693 // committed table resizing go even though the committed |
|
694 // table will over state the committed space. |
687 } |
695 } |
688 } |
696 } |
|
697 #else |
|
698 assert(!result, "Should be false with current workaround"); |
|
699 #endif |
689 } |
700 } |
690 assert(_committed[changed_region].end() == cur_committed.end(), |
701 assert(_committed[changed_region].end() == cur_committed.end(), |
691 "end should not change"); |
702 "end should not change"); |
|
703 return result; |
692 } |
704 } |
693 |
705 |
694 void CardTableExtension::resize_update_committed_table(int changed_region, |
706 void CardTableExtension::resize_update_committed_table(int changed_region, |
695 MemRegion new_region) { |
707 MemRegion new_region) { |
696 |
708 |