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