Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp @ 1612:fdde661c8e06
6952853: SIGSEGV with UseAdaptiveGCBoundary on 64b linux running jvm2008
Summary: Shrinking of a generation and the corresponding card table was causing part of the card table to be uncommitted.
Reviewed-by: jcoomes
author | jmasa |
---|---|
date | Wed, 23 Jun 2010 08:35:31 -0700 |
parents | c18cbe5936b8 |
children | 9d7a8ab3736b |
comparison
equal
deleted
inserted
replaced
1594:b9bc732be7c0 | 1612:fdde661c8e06 |
---|---|
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 |